2011-06-29 62 views
4

我有一個表單允許一個文件附件,並生成一個電子郵件到一個硬編碼的地址。我想避免惡意用戶輸入自定義郵件標題的可能性(一種CRLF注入,因爲電子郵件標題按照RFC的規定以\ r \ n結尾)。我可以通過替換JUST CR來避免CRLF注入攻擊嗎?

假設我運行的每一塊數據如下功能可能使其進入$additional_headers參數:

<?php 

function strip_crlf($string){ return str_replace("\r\n", "\n", $string); } 

?> 

替換隻是CRLF對的回車一半。這是否能夠充分防止潛在的攻擊?

通常我會用空字符串替換\ r \ n。但是這個特殊的表單允許有一個附件,這意味着郵件正文實際上已經通過$ additional_headers參數傳遞,因爲PHP沒有用於構建多部分MIME編碼電子郵件的本地函數(我知道)。

萬一有人關心,這是我的郵件附件功能:

<?php 
function mail_attachment($to, $from, $from_name, $subject, $message, $file = false, $filename = false, $filetype = false){ 

    // Remove CRLF sequences from everything that might go into a header 
    $from = strip_crlf($from); 
    $from_name = strip_crlf($from_name); 
    $message = strip_crlf($message); 
    if($filename){ $filename = strip_crlf($filename); } 
    if($filetype){ $filetype = strip_crlf($filetype); } 

    // $to and $subject escaping handled natively by mail(); 
    // $file is base64 encoded before mail_attachment() is called. 

    $header = ''; 

    // No file attachment; just send a regular email. 
    if(!$file){ 
     $header .= "From: ".$from_name." <".$from.">\r\n"; 
     return mail($to, $subject, $message, $header); 
    } 

    $uid = md5(uniqid(time())); 

    // Build a MIME encoded message. 
    $header .= "MIME-Version: 1.0\r\n"; 
    $header .= "Content-Type: multipart/mixed; boundary=\"$uid\"\r\n\r\n"; 
    $header .= "This is a multi-part message in MIME format.\r\n"; 
    $header .= "--$uid\r\n"; 
    $header .= "Content-type:text/plain; charset=utf-8\r\n"; 
    $header .= "Content-Transfer-Encoding: 8bit\r\n\r\n"; 
    $header .= "$message\r\n\r\n"; 
    $header .= "--$uid\r\n"; 
    $header .= "Content-Type: $filetype; name=\"$filename\"\r\n"; 
    $header .= "Content-Transfer-Encoding: base64\r\n"; 
    $header .= "Content-Disposition: attachment; filename=\"$filename\"\r\n\r\n"; 
    $header .= "$file\r\n\r\n"; 
    $header .= "--$uid--"; 

    // Send the mail. 
    return mail($to, $subject, '', $header); 
} 

?> 
+3

'strip_crlf(「\ r \ r \ n」)'變成'「\ r \ n」' – Zikes

+0

Ooo,很好!即使我可以依靠電子郵件服務器來遵守約定,我的分條功能也不可靠。 +1。 –

回答

3

不,只替換CR是不夠的 - 有足夠的郵件客戶端只查看可被利用的LF。當然,大多數標題字段都不需要換行符,所有,所以你可以簡單地從除了$message以外的所有東西中去除CR和LF。對於$message,請確保它不包含您的MIME分隔符(在這種情況下爲--$uid),或將其編碼爲base64或其他內容。

+0

我會接受這個,因爲它直接回答問題。不過,我可能會遵循Swiftmailer/PHPMailer的建議。謝謝! –

5

如果你擔心注射,然後不建立自己的消息。使用SwiftmailerPHPMailer,爲您照顧所有這些擔憂。

+0

我會仔細看看這兩個,謝謝。 –

相關問題