Can I avoid CRLF injections by replacing JUST CR?

I have a form that allows one file attachment, and generates an email to a hard address. I would like to avoid the possibility of malicious users getting into custom message headers (CRLF injection, so-called, because email headers end with \ r \ n in accordance with the RFC).

Assume that for each piece of data that can add it to the $ Additional_headers parameter, execute the following function:

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

This replaces ONLY half the carriage return of the CRLF pair. Will this prevent potential attacks adequately?

Normally I would just replace \ r \ n with an empty string. But this particular form allows one attachment, which means that the message body really ends by going through the $ Additional_headers parameter, because PHP does not have a built-in function for creating a multi-line MIME-encoded letter (which I know).

In case someone cares, here is my function for sending attachments:

 <?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
source share
2 answers

No, replacing just CR is not enough - there are enough email clients who only look at LF that can be used. Of course, most header fields don't need newlines, so you can just turn off both CR and LF from everything except $message . For $message either make sure it cannot contain your MIME delimiter ( --$uid in this case), or encode it as base64 or something like that.

+3
source

If you are worried about injections, do not create your own posts. Use Swiftmailer or PHPMailer , which take care of all those who care about you.

+5
source

All Articles