Могу ли я избежать CRLF-инъекций, заменив ПРОСТО CR? - PullRequest
4 голосов
/ 30 июня 2011

У меня есть форма, которая позволяет вложение одного файла, и генерирует электронную почту на жестко закодированный адрес.Я хотел бы избежать возможности злоумышленников вводить пользовательские заголовки почты (внедрение CRLF, так называемые, поскольку заголовки писем заканчиваются на \ r \ n согласно RFC).

Предположим, я запускаю следующую функцию для каждого элементаданных, которые могут попасть в параметр $ 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);
}

?>

Ответы [ 2 ]

5 голосов
/ 30 июня 2011

Если вы беспокоитесь об уколах, не создавайте свои собственные сообщения. Используйте Swiftmailer или PHPMailer , который позаботится обо всех этих заботах за вас.

3 голосов
/ 30 июня 2011

Нет, замена только CR недостаточна - достаточно почтовых клиентов, которые смотрят только на LF, чтобы его можно было использовать. Конечно, большинству полей заголовка вообще не нужны символы новой строки , так что вы можете просто удалить CR и LF из всего, кроме $message. Для $message либо убедитесь, что он не может содержать разделитель MIME (в данном случае --$uid), либо закодируйте его как base64 или что-то в этом роде.

...