Mail Header Injections
How to protect a php Email Form using php mail or mb_send_mail
against
Mail Header Injection
The php functions mail and mb_send_mail have the following parameters (simplified):
mail ($recipient, $subject, $message, $header);
mb_send_mail
($recipient, $subject, $message, $header);
Sample:
The text input saved in the variable $email should be used as sender of the message:
$header="From: $email\r\nMIME-Version: 1.0\r\nContent-type: text/html; charset=utf-8";
Lets say a regular user (good guy) enters his email address: "someone@somedomain.tld"
in the text input field.
The header would look like this:
From: someone@somedomain.tld
MIME-Version: 1.0
Content-type:
text/html; charset=utf-8
warning If an attacker (bad guy) enters the following code in the text input field:
someone@somedomain.tld%0ACc:someoneelse@somedomain.tld%0ABcc:anotherone@somedomain.tld ...
This would "inject" a CC (Carbon Copy) and a BCC
(Blind Carbon Copy) to the email header.
The %0A results in a new line in
the mail header, which allows the injection.
From: someone@somedomain.tld
CC: someoneelse@somedomain.tld
BCC: anotherone@somedomain.tld
...
MIME-Version: 1.0
Content-type:
text/html; charset=utf-8
warning Such an injected form can be used to send email messages to any recipient!
How to Protect your Form?
There is one golden rule: Never use any unfiltered user input!
You can e.g. use the php filter_var function to filter the user input:
$email = filter_var($email,FILTER_VALIDATE_EMAIL);
The built-in php function checks the email address for the correct syntax.
An injected input field should not pass the php email address verification.
In addition: You should also filter any user input included in the subject
line (or any other header field).
You can use something like e.g.:
$filter_array = array('/(\n+)/i','/(\r+)/i','/(\t+)/i','/(%0A+)/i','/(%0D+)/i','/(%08+)/i','/(%09+)/i');
$good_string = preg_replace($filter_array,'',$bad_string);