【问题标题】:Is "strip_tags" sufficient for contact form security?“strip_tags”对于联系表单的安全性是否足够?
【发布时间】:2015-10-16 01:31:04
【问题描述】:

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

这是表格:

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

【问题讨论】:

  • 是否有任何用户输入?
  • 你应该发布过滤消息的任何代码,你提到 strip_tags 但不要显示它。
  • 我不知道任何运行 javascript 的电子邮件客户端,因此 XSS 不适用,除非您还在“感谢”页面上重新显示提交的内容。不要将提交者的电子邮件地址用作from 地址,因为这会使您无法通过 SPF 检查;把它放在reply-to 中。你为什么要传入$mail 实例?看起来将它作为本地静态可能会更好,或者您需要小心在调用之间清除收件人。
  • $mail 变量在函数范围之外,如果您不传递邮件对象,它会引发服务器错误。感谢您提供有关 SPF 检查的提示。这真的很有用。将其设置为 webmaster@mydomain.com 并将名称设置为 mydomain.com 是否有效。或者只是将电子邮件地址设置为 webmaster@mydomain.com,名称可以是发送邮件的人的姓名?

标签: php security phpmailer contact-form


【解决方案1】:

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】:

    没有。

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

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

    【讨论】:

    • 我正在运行的函数不应该允许这样做,它需要非常具体的变量,然后运行另一个函数来发送电子邮件。并且目标地址在函数中是硬编码的。我想我最担心的是脚本攻击。尽管如此,我还是尝试了一个简单的测试,将“”放入name字段并提交,没有任何反应(还没有使用strip_tags),所以可能完全不用担心
    【解决方案3】:

    此外,您可以使用 PHP 函数来清理每个 INPUT:

    <?php
    
     $name = filter_input(INPUT_POST, $_POST['name'], FILTER_SANITIZE_STRING);
     $email = filter_input(INPUT_POST, $_POST['email'], FILTER_SANITIZE_EMAIL);
     $address = filter_input(INPUT_POST, $_POST['address'], FILTER_SANITIZE_STRING);
     $message = filter_input(INPUT_POST, $_POST['message'], FILTER_SANITIZE_STRING);
    
    ?>
    

    或者您可以为 args 创建一个数组并通过所有验证:

    <?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);
    
    ?>
    

    这是为了防止 XSS 攻击。

    这里所有类型的过滤器:Input Filters PHP

    另外,作为额外提示,在清理每个“INPUT”后,您可以简化“EMPTY”检查,只使用“ISSET”(更快):

    <?php
        if(isset($to{1}, $subject{1}, $senderName{1}, $from{1}, $message{1}))
        {
          //code...
        }
    ?>
    

    这意味着所有变量必须至少有一个字符,否则代码将永远不会被执行。

    【讨论】:

    • 太棒了。所以这会保护网站和接收电子邮件的用户?
    • 基本上,正如他们的名字所说,这个过滤器会清理输入 POST 或 GET。此过滤器可以删除额外的标签并将变量转换为纯文本。
    【解决方案4】:

    接收安全输入数据的最佳方法是为数据构建安全模型。

    应该定义哪些数据可以在表单中输入,系统需要接收哪些数据。

    基于这一知识,人们应该验证和过滤除真正需要之外的所有内容。

    因此,如果您知道自己在做什么,那么您现在应该知道该功能、方法或更好的方法是否足以保护数据。

    不应依赖简单的函数,而应使用建模方法。

    附:请阅读有关输入数据验证的更多信息Data Validation

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-06-06
      • 1970-01-01
      • 2011-04-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多