是" strip_tags"足够的联系表格安全?

时间:2015-10-16 01:31:04

标签: php security phpmailer contact-form

我的网站上有一个联系表单,它将用户姓名,电子邮件地址,主题和消息的发布值提交给使用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>

这是表格:enter image description here

然后它发布:sendEmail($mail, $contactEmail, $_POST['subject'], $_POST['sender_name'], $_POST['sender_email'], $_POST['body']);,其中$ contactEmail是从我的数据库中提取的地址。然后该函数使用phpmailer发送电子邮件地址。

4 个答案:

答案 0 :(得分:0)

没有

您需要检查邮件以确保没有向To:,CC:和BCC注入标头:这将允许垃圾邮件发送者从您的表单发送电子邮件。

这篇文章有其他信息:How to sanitze user input in PHP before mailing?

答案 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