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