Filed under Web Development

Form injection is one of the most common security issue on the web. Bots or scripts are continuously crawling the web in search of entry forms. When they find one, they try to submit it while injecting malicious instructions into some of the form’s fields. These instructions may go from SQL queries to SMTP commands.

Email form injection is what we’ll be discussing about today. This form of attack is mainly used to send spam mail through the exploited server. We’ll see what precaution we can take by validating the input before it is sent to server and after it is being sent but just before processing it.


Let’s say we want to secure this simple email form:

Preventing Email Form Injection

Client-Side Protection

There are a some precautions you can take on the client-side (before the form is submitted) in order to avoid email form injection:

  • Limit the maximum length of each field so that it may be harder to inject malicious instructions (while still not totally impossible);
  • Add an additional field to require an anti-spam question (like 2+3=?) to ensure it’s being accessed by a human and not a script;
  • Replace text fields by dropdown menus or checkboxes where possible (does not apply for the above form example);

Server-Side Protection And Validation

In order to prevent form injection, let’s start by validating the sender’s email address using the preg_match function. The following would prevent an email to be sent if the sender’s email address format is incorrect:

<?
$email_pattern = ‘/^[^@\s]+@([-a-z0-9]+\.)+[a-z]{2,}$/i’;

if (!preg_match($email_pattern, $sender_email)){
  die(“Your email address is incorrect”);
}
?>

Next we could filter out carriage returns from text fields (but not text areas of course):

<?
if (eregi(“(\r|\n)”, $subject))
     die(“Form injection detected”);
?>

Making sure that the validation script is being sent data from a browser will also rule out some bots:

<?
if(!isset($_SERVER['HTTP_USER_AGENT'])){
   die(“Forbidden – You are not authorized to view this page”);
   exit;
}
?>

There are also a few strings you may want to make sure they aren’t passed to your script:

$badstrings = array(“Content-Type:”,
                     “MIME-Version:”,
                     “Content-Transfer-Encoding:”,
                     “bcc:”,
                     “cc:”);

foreach($_POST as $key => $value){
   foreach($badstrings as $badstring){
       if(strpos($value, $badstring) !== false){
          die(“Forbidden – You are not authorized to view this page”);
          exit;
       }
   }
}

I’ve got another post where you can learn more on how to send emails with PHP.


Related Posts

Comments (0) Posted by Stephane on Sunday, October 21st, 2007


You can follow any responses to this entry through the magic of "RSS 2.0" and leave a trackback from your own site.

Post A Comment