2010-05-26 71 views
0

我已经终于得到这个PHP电子邮件脚本工作(没有在本地主机上工作...),但我担心的是,这是不安全的。这是一个安全的PHP邮件功能吗?

所以 - 这是安全的垃圾邮件和任何其他安全缺陷,我不知道?

<?php 
$email = '[email protected]'; 
$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代替正则表达式

<?php 
$email = '[email protected]'; 
$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>"; 
} 
?> 

回答

4

剧本我不知道,如果ID使用$_SERVER['HTTP_REFERER']回去。我觉得这可能会让你打开攻击,因为它是通过请求设置的。做到这一点的方法是在前一页使用会话。这样你就不会将不可信的数据转储到你的网站上。

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

+0

+1为过滤器。太好了! – Cam 2010-05-26 04:53:00

+0

+1用于过滤器,不信任引荐者!或者使用上面提到的会话,或者重定向到用户应该来自的地方。 – 2010-05-26 04:59:11

+0

谢谢,不知道过滤器。我已更新原始帖子。 – Eystein 2010-05-26 07:55:01

1

如果您想接受所有有效形成的电子邮件地址并拒绝所有无效的电子邮件地址,那么您不能仅仅使用正则表达式将电子邮件地址与短正则表达式模式匹配。使用解析器(1,2),实际上针对相关的RFC实施以检查有效性。

您可以做的其他事情是检查HTTP_REFERER以确保请求来自您的域名为Chacha102已经提到。请注意,并非所有代理都发送HTTP_REFERER,并且可以选择关闭或伪造用户。

如果您想额外付出一定的努力以确保他们给您一个有效的电子邮件地址,您可以检查指定域(A,MX或AAAA)的邮件服务器的现有DNS记录。最重要的是,你可以做回调验证。这就是你连接到邮件服务器的地方,告诉它你想发送到这个邮件地址,看看他们是否说好。

对于回拨验证,您应该注意灰名单服务器对一切都说OK,即使这不是保证。以下是我需要这样的脚本时使用的一些代码。这是来自(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;