如何保护发送电子邮件的表单

时间:2013-08-25 16:41:07

标签: php phpmailer recaptcha

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

这对于生产环境来说是否足够好/安全。即它会停止机器人,卷曲脚本使用它发送垃圾邮件,并停止电子邮件注入等?

<?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!";

        }

    }

?>

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

6 个答案:

答案 0 :(得分:4)

我之前没有使用过php邮件,但它应该注意安全,逃避等。
您的代码看起来不错:

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

    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地址 - 对于他喜欢垃圾邮件的情况,你可以轻松阻止他。

答案 1 :(得分:4)

我建议另外两个选择:

我。)您可以在发送表单中添加额外的输入txt字段,然后使用css样式隐藏(看不见)用户,例如。

<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,如果他们在网站上授权时发送电子邮件等)并阻止他们多次发送类似的电子邮件连续(在很短的时间内)。 您还可以实施一些规则来过滤垃圾邮件机器人。 F.e.,如果用户尝试过于频繁地发送,则可能会被阻止。另一个选择是拥有授权用户的“白名单”,他们可以发送更自由和更广泛限制的邮件。

答案 2 :(得分:3)

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

所以你不应该允许任何标题中的任何换行符(to,subject)

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地址。这是一个流行的服务器,保护它不发送垃圾邮件非常重要;对于一般用途,你的代码足够好。

答案 3 :(得分:0)

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

答案 4 :(得分:0)

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

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

在我看来,最好的方法是吃掉垃圾邮件,然后用SpamAssassin之类的东西过滤掉垃圾邮件,这样你就可以删除验证码(放一些honeypot fields来抓住大部分僵尸程序)和在过滤掉大部分垃圾邮件的同时改善用户体验。

答案 5 :(得分: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!";

    }