这是一个安全的PHP邮件功能吗?

时间:2010-05-26 03:49:20

标签: php security email

终于让这个PHP电子邮件脚本正常工作(无法在localhost上运行...),但我担心的是它不安全。

那么 - 这对于垃圾邮件以及我不知道的任何其他安全隐患是否安全?

<?php
$email = 'notification@domain.com';
$subject = 'Notify about stuff';
$notify = $_REQUEST['email'];

if (!preg_match("/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/", $notify)) {
    echo "<h4>Your email address doesn't validate, please check that you typed it correct.</h4>";
    echo "<a href='javascript:history.back(1);'>Back</a>";
}

elseif(mail($email, $subject, $notify)) {
    echo "<h4>Thank you, you will be notified.</h4>";
} else {
    echo "<h4>Sorry, your email didn't get registered.</h4>";
}
?>

无关:我可以使用PHP函数代替javascript:history.back(1)吗?

编辑:脚本使用filter而不是RegEx

<?php
$email = 'notification@domain.com';
$subject = 'Notify about stuff';
$notify = $_REQUEST['email'];

if (!filter_var($notify, FILTER_VALIDATE_EMAIL)) {
    echo "<h4>This email address ($notify) is not considered valid, please check that you typed it correct.</h4>";
    echo "<a href='javascript:history.back(1);'>Back</a>";
}

elseif(mail($email, $subject, $notify)) {
    echo "<h4>Thank you, you will be notified.</h4>";
} else {
    echo "<h4>Sorry, your email didn't get registered.</h4>";
}
?>

2 个答案:

答案 0 :(得分:5)

我不知道id是否使用$_SERVER['HTTP_REFERER']返回。我觉得这可以让你受到攻击,因为它是通过请求设置的。这样做的方法是使用上一页的会话。这样您就不会将不值得信任的数据转储到您的网站上。

我没有看到任何安全风险,但在检查电子邮件的有效性时,我建议使用filter。它比弄乱RE更容易。

答案 1 :(得分:1)

如果您希望接受所有有效格式的电子邮件地址并拒绝所有无效的电子邮件地址,则不能仅将regexp匹配电子邮件地址与短的正则表达式模式匹配。使用实际针对相关RFC实施的解析器(12)来检查其有效性。

您可以执行的其他操作是检查HTTP_REFERER以确保请求来自您的域中 Chacha102 已经提到过。请注意,并非所有代理都发送HTTP_REFERER,并且用户可以选择关闭或伪造它。

如果您想加倍努力以确保他们为您提供有效的电子邮件地址,您可以检查指定域(A,MX或AAAA)上的邮件服务器的现有DNS记录。最重要的是,您可以进行回调验证。这是你连接到邮件服务器的地方,告诉你要发送到这个电子邮件地址,看看他们是否说好。

对于回拨验证,您应该注意灰名单服务器对所有内容都说好,所以即使这不是保证。这是我在需要这样一个脚本时使用的一些代码。它是来自(1)的解析器的补丁。

    #
    # Email callback verification
    # Based on http://uk2.php.net/manual/en/function.getmxrr.php
    #

    if (strlen($bits['domain-literal'])){
        $records = array($bits['domain-literal']);
    }elseif (!getmxrr($bits['domain'], $mx_records, $mx_weight)){
        $records = array($bits['domain']);
    }else{
        $mxs = array();

        for ($i = 0; $i < count($mx_records); $i++){
            $mxs[$mx_records[$i]] = $mx_weight[$i];
        }

        asort($mxs);

        $records = array_keys($mxs);
    }

    $user_okay = false;
    for ($j = 0; $j < count($records) && !$user_okay; $j++){
        $fp = @fsockopen($records[$j], 25, $errno, $errstr, 2);
        if($fp){
            $ms_resp = "";

            $ms_resp .= send_command($fp, "HELO ******.com");
            $ms_resp .= send_command($fp, "MAIL FROM:<>");

            $rcpt_text = send_command($fp, "RCPT TO:<" . $email . ">");
            $ms_resp .= $rcpt_text;

            $ms_code = intval(substr($rcpt_text, 0, 3));
            if ($ms_code == 250 || $ms_code == 451){ // Accept all user account on greylisting server
                $user_okay = true;
            }

            $ms_resp .= send_command($fp, "QUIT");

            fclose($fp);
        }
    }

return $user_okay ? 1 : 0;