3

我有以下发送电子邮件的代码。

这对于生产环境是否足够好/安全。即它会阻止机器人、使用它发送垃圾邮件的 curl 脚本以及停止电子邮件注入等吗?

<?php

    require_once('recaptchalib.php');
    $privatekey = "private keys goes here";
    $resp = recaptcha_check_answer ($privatekey,
                                    $_SERVER["REMOTE_ADDR"],
                                    $_POST["recaptcha_challenge_field"],
                                    $_POST["recaptcha_response_field"]);

    if (!$resp->is_valid) {

        // What happens when the CAPTCHA was entered incorrectly
        die ("The reCAPTCHA wasn't entered correctly. Go back and try it again. " .
             "(reCAPTCHA said: " . $resp->error . ")");

    } else {

        require 'class.phpmailer.php';

        //Create a new PHPMailer instance
        $mail = new PHPMailer();

        //Set who the message is to be sent from
        $mail->SetFrom('oshirowanen@localhost.com');

        //Set who the message is to be sent to
        $mail->AddAddress($_POST['email']);

        //Set the subject line
        $mail->Subject = 'subject goes here';

        //Replace the plain text body with one created manually
        $mail->Body = $_POST['message'];

        //Send the message, check for errors
        if(!$mail->Send()) {

            die ("Mailer Error: " . $mail->ErrorInfo);

        } else {

            echo "Message sent!";

        }

    }

?>

所以基本上,我要问的是,上面的代码对于生产环境是否足够安全、足够安全、足够好?

4

6 回答 6

4

我以前没有使用过 php mailer,但它应该注意安全、转义等。
但是你的代码看起来不错:

  • 我会通过在发送之前添加编码检查来改进脚本 - 例如这样:

    iconv("UTF-8", "UTF-8//IGNORE", $subject_or_message_or_any_string);
    
  • 如果邮件发送失败,我也不会显示信息,而不是我宁愿使用类似的东西:

    if (!$mail->Send())
    {
        LogErrorMessage("Mailer Error: %s", $mail->ErrorInfo);
        die ("Sorry, mail could not be sent");
    }
    
  • 接下来,我将发送或记录发送电子邮件表单的用户的 IP 地址 - 对于他喜欢发送垃圾邮件的情况,您可以轻松阻止他。

于 2013-08-27T20:15:29.757 回答
4

我会建议另外2个选项:

I.) 您可以在发送表单中放置额外的输入 txt 字段,然后使用 css 样式将它们隐藏(不可见)给用户,fe

<input type="text" id="commentary" style="display: none;">
<!-- OR -->
<input type="text" id="commentary" style="opacity: 0;">
<!-- OR -->
<input type="text" id="commentary" style="position: absolute; left: -100px; top: -100px;">

<!-- 
The trick is, user won't see these forms and WILL NOT FILL THEM. 
And bot will, so you can easily filter them without even using CAPTCHA. 
-->

II.) 您可以创建一个用户列表(包括他们的 IP、姓名、Cookie-ID、用户 ID,如果他们在网站上授权时发送电子邮件等),并防止他们连续多次发送类似的电子邮件(在短时间内)。您还可以实施一些规则来过滤垃圾邮件机器人。Fe,如果用户尝试发送太频繁,那么它可能会被阻止。另一种选择是拥有授权用户的“白名单”,他们将能够以更大的自由度和更广泛的限制发送邮件。

于 2013-08-29T10:01:40.270 回答
3

对于那些不知道什么是标头注入(称为 OP 电子邮件注入)的人:即使我们假设验证码是不可破解的,人类也可以填写您的表单,添加一些垃圾邮件评论,并插入包含数千封电子邮件的 BCC 标头地址,您的脚本将发送它们。

所以你不应该在任何标题(到,主题)中允许任何换行符

PHPMailer 负责这个,这里是代码的相关部分:

$name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim
if (!$this->ValidateAddress($address)) {
   $this->SetError($this->Lang('invalid_address').': '. $address);

Recaptcha 是易碎的,并且可以发送一些垃圾邮件。您有效地限制了垃圾邮件,但如果不允许任何垃圾邮件很重要,那么您需要对电子邮件内容进行垃圾邮件过滤器,因为您永远无法保证表单不会由想要的人发送发送一些垃圾邮件。或者,您可以添加每小时从给定 IP 发送的消息的限制,这样您就可以有效地限制可以发送的垃圾邮件数量,即使验证码被破解或有人正在填充它。并且您可以添加一个检查,以使相同的消息内容不能发送到 X 个以上的地址。如果它是一个流行的服务器,那么保护它不发送垃圾邮件非常重要;对于一般用途,您的代码已经足够好了。

于 2013-08-31T13:01:58.303 回答
0

是的,您的代码应该可以工作,您有一个验证码,因此机器人或脚本无法通过它发送垃圾邮件,并且 PHPMailer 已经受到电子邮件标题注入的保护,因此您可以免受攻击者滥用您的联系表发送垃圾邮件其他人。

然而,没有什么能阻止人类手动填写验证码并以这种方式向您发送垃圾邮件,不幸的是,您对此无能为力(可能会限制每个 IP 每天的消息数量,因此即使是手动垃圾邮件发送者也只能发送一些每天的消息)。

在我看来,最好的方法是吃掉垃圾邮件,然后用 SpamAssassin 之类的东西过滤它,这样你就可以删除验证码(放置一些蜜罐字段来捕获大多数机器人)并改善你的用户体验,同时仍然过滤掉大部分垃圾邮件。

于 2013-08-27T19:54:42.433 回答
0

reCaptcha 是一个很好的反垃圾邮件脚本。对于电子邮件机器人,请检查您的页面源以隐藏机器人可读的任何电子邮件,如下所示:Encrypt mailto email addresses with inline JavaScript

于 2013-08-27T19:50:00.200 回答
0

如果您仍然觉得它不安全,那么您可以为其添加更多安全性。
在表格中添加:

<input name="url" style="display:none">

然后在此修改代码之后:

else if($_REQUEST['url']){

    require 'class.phpmailer.php';

    //Create a new PHPMailer instance
    $mail = new PHPMailer();

    //Set who the message is to be sent from
    $mail->SetFrom('oshirowanen@localhost.com');

    //Set who the message is to be sent to
    $mail->AddAddress($_POST['email']);

    //Set the subject line
    $mail->Subject = 'subject goes here';

    //Replace the plain text body with one created manually
    $mail->Body = $_POST['message'];

    //Send the message, check for errors
    if(!$mail->Send()) {

        die ("Mailer Error: " . $mail->ErrorInfo);

    } else {

        echo "Message sent!";

    }
于 2013-09-02T10:26:25.353 回答