Pertanyaan Dapatkah saya menghindari serangan injeksi CRLF dengan mengganti HANYA CR?


Saya memiliki formulir yang memungkinkan satu lampiran file, dan menghasilkan email ke alamat hard-coded. Saya ingin menghindari kemungkinan pengguna jahat memasukkan header surat kustom (injeksi CRLF, disebut demikian karena header email diakhiri dengan \ r \ n sesuai RFC).

Misalkan saya menjalankan fungsi berikut pada setiap bagian data yang mungkin membuatnya menjadi $ additional_headers parameter:

<?php

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

?>

Yang menggantikan HANYA carriage return half dari pasangan CRLF. Apakah itu akan mencegah serangan potensial secara memadai?

Biasanya saya hanya akan mengganti \ r \ n dengan string kosong. Tetapi bentuk khusus ini memungkinkan untuk satu lampiran, yang berarti bahwa badan pesan benar-benar berakhir melalui parameter $ additional_headers karena PHP tidak memiliki fungsi asli untuk membangun email yang dikodekan multimode MIME (yang saya tahu).

Jika ada yang peduli, inilah fungsi saya untuk mengirimkan lampiran:

<?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);
}

?>

4
2018-06-29 22:03


asal


Jawaban:


Tidak, mengganti hanya CR saja tidak cukup - ada cukup klien email yang hanya melihat pada LF yang dapat dieksploitasi. Tentu saja, sebagian besar bidang header tidak memerlukan baris baru sama sekali, jadi Anda cukup melucuti CR dan LF dari semuanya kecuali $message. Untuk $message, pastikan itu tidak dapat memuat seperator MIME Anda (--$uid dalam hal ini), atau menyandikannya sebagai base64 atau sesuatu.


3
2018-06-29 22:07



Jika Anda khawatir tentang suntikan, maka jangan membuat pesan Anda sendiri. Menggunakan Swiftmailer atau PHPMailer, yang mengurus semua kekhawatiran itu untukmu.


5
2018-06-29 22:07