我的网站上有一个联系表单,它将用户姓名,电子邮件地址,主题和消息的发布值提交给使用phpmailer发送电子邮件的函数。使用strip_tags足以使这种形式安全吗?我还没有实现这个。
function sendEmail($mail, $to, $subject, $senderName, $from, $message) {
if((!empty($to)) && (!empty($subject)) && (!empty($senderName)) && (!empty($from)) && (!empty($message))) {
$mail->isSMTP(); // Set mailer to use SMTP
$mail->Host = '[REDACTED]'; // Specify main and backup SMTP servers
$mail->SMTPAuth = true; // Enable SMTP authentication
$mail->Username = '[REDACTED]'; // SMTP username
$mail->Password = '[REDACTED]'; // SMTP password
$mail->SMTPSecure = 'tls'; // Enable TLS encryption, `ssl` also accepted
$mail->Port = 587; // TCP port to connect to
$mail->setFrom($from, $senderName); //
$mail->addAddress('[REDACTED]', '[REDACTED]'); // Add a recipient. Hardcoded email address
$mail->addReplyTo($from, $senderName);
$mail->Subject = $subject;
$mail->Body = "<h1>You've received a message through the contact form at chriscomposes.com</h1><br><br>" . $message;
$mail->AltBody = "You've received a message through the contact form at chriscomposes.com." . $message;
if(!$mail->send()) {
return "<p style='margin-left: 5px; color: red;'>Message failed to send.</p>";
} else {
return "<p style='margin-left: 5px; color: green;'>Message has been sent.</p>";
}
} else {
return "<p style='margin-left: 5px; color: red;'>One or more fields are empty. Please enter a subject, name, email address, and message.</p>";
}
}
^这是它运行的功能。使用硬编码的电子邮件地址,我不认为使用该表单发送电子邮件的人很容易受到攻击。另一个问题是接收地址的用户容易受到插入电子邮件中的javascript的攻击。</ p>
然后它发布:sendEmail($mail, $contactEmail, $_POST['subject'], $_POST['sender_name'], $_POST['sender_email'], $_POST['body']);
,其中$ contactEmail是从我的数据库中提取的地址。然后该函数使用phpmailer发送电子邮件地址。
答案 0 :(得分:0)
没有
您需要检查邮件以确保没有向To:,CC:和BCC注入标头:这将允许垃圾邮件发送者从您的表单发送电子邮件。
答案 1 :(得分:0)
PHP有一个名为filter_var
的数据过滤功能,您可以使用它。
http://php.net/manual/en/filter.examples.sanitization.php
汇总电子邮件地址,主题和正文都是用户输入数据,
$sanitizedEmail = filter_var($email, FILTER_SANITIZE_EMAIL);
$sanitizedSubject = filter_var($subject, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW);
$sanitizedBody = filter_val($body, FILTER_SANITIZE_STRING);
FILTER_SANITIZE_STRING
会移除标签并对特殊字符进行编码
FILTER_FLAG_STRIP_LOW
会删除换行符,因为您不需要主题字段中的换行符。
答案 2 :(得分:0)
此外,您可以使用PHP函数来清理每个INPUT:
<?php
$args = [
'name' => FILTER_SANITIZE_STRING,
'email' => FILTER_SANITIZE_EMAIL,
'address' => FILTER_SANITIZE_STRING,
'message' => FILTER_SANITIZE_STRING,
];
$myInputs = filter_input_array(INPUT_POST, $args);
?>
或者您可以为args创建一个数组并传递所有验证:
<?php
if(isset($to{1}, $subject{1}, $senderName{1}, $from{1}, $message{1}))
{
//code...
}
?>
这可以防止XSS攻击。
此处所有类型过滤器:Input Filters PHP
而且,作为额外提示,在清理每个“INPUT”之后,您可以简化“EMPTY”检查,仅使用“ISSET”(更快):
/*
* returns fields that have getter/setters including nested fields as
* field0, objA.field1, objA.objB.field2, ...
* to take care of recursive duplicates,
* simply use a set<Class> to track which classes
* have already been traversed
*/
public static void getBeanUtilsNestedFields(String prefix,
Class clazz, List<String> nestedFieldNames) throws Exception {
PropertyDescriptor[] descriptors = BeanUtils.getPropertyDescriptors(clazz);
for(PropertyDescriptor descr : descriptors){
// if you want values, use: descr.getValue(attributeName)
if(descr.getPropertyType().getName().equals("java.lang.Class")){
continue;
}
// a primitive, a CharSequence(String), Number, Date, URI, URL, Locale, Class, or corresponding array
// or add more like UUID or other types
if(!BeanUtils.isSimpleProperty(descr.getPropertyType())){
Field collectionfield = clazz.getDeclaredField(descr.getName());
if(collectionfield.getGenericType() instanceof ParameterizedType){
ParameterizedType integerListType = (ParameterizedType) collectionfield.getGenericType();
Class<?> actualClazz = (Class<?>) integerListType.getActualTypeArguments()[0];
getBeanUtilsNestedFields(descr.getName(), actualClazz, nestedFieldNames);
}
else{ // or a complex custom type to get nested fields
getBeanUtilsNestedFields(descr.getName(), descr.getPropertyType(), nestedFieldNames);
}
}
else{
nestedFieldNames.add(prefix.concat(".").concat(descr.getDisplayName()));
}
}
}
这意味着所有变量必须至少包含一个char,否则代码将永远不会被执行。
答案 3 :(得分:0)
接收安全输入数据的最佳方法是为数据构建安全模型。
应该定义可以在表单中输入的数据以及系统需要接收的数据。
基于这些知识,人们应该验证并过滤掉除了真正需要的东西之外的一切。
因此,如果您知道自己在做什么,那么如果该功能,方法或更好的方法足以保护数据,那么您应该知道。
人们不应该依赖简单的功能,而应该使用建模方法。
P.S。请阅读有关输入数据验证的更多信息Data Validation。