2010-05-26 66 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;