Tips and Tricks

How to protect a php Email Form using php mail or mb_send_mail
against Mail Header Injection

Build Online Forms for your own Web Site !

Arclab® Web Form Builder the HTML form creation software for Windows PC to create email contact forms and
multi-page php forms with ease. Build HTML forms on your PC and upload the forms to your own web site.


Arclab Web Form Builder Homepage

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



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

Now 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

Now the injected form can be used to send email messages to any recipient!


Arclab Web Form Builder is protected against such an attack in multiple ways:

It checks the email address for the correct syntax if you use the "Email Address Input Element" in the program. An injected input field will not pass the email address verification.

function is_email_valid($a)
{ return preg_match('/^[A-Z0-9._%-]+@[A-Z0-9][A-Z0-9.-]{0,61}[A-Z0-9]\.[A-Z]{2,6}$/i',$a); }

The injection will not work, even if you don't use the "Email Address Input Element", because we use another filter function to filter out the characters required for the injection:

$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);

There are multiple lines of defense to secure the script agains php mail header injections.
Arclab Web Form Builder also filters the subject if you use a form variable in the subject line.