Reinspire

You are viewing an archived page from the 1st version of my site, but I've started over. You can find the latest content and design at www.reinspire.net, or read all about the relaunch here.

February 25, 2006

Securing PHP Mail Forms

Over the past several days, I’ve been doing a fair amount of research on PHP’s Mail function and the specific vulnerabilities that it suffers from. Because of the way the Mail function works, there are specific ways that hackers or spam-bots can utilize seemingly innocent forms to spread their spam.

Now don’t get me wrong, I’m not criticizing PHP’s Mail function or it’s developers in any way. On the contrary, I find that PHP’s Mail function is well thought out and very powerful. However, to quote a line from the movie ‘Spider-Man:’

“With great power comes great responsibility.”

Unfortunately the world we’re living in is full of people just waiting to take advantage of other people. The anonymity factor that is inherent on the Internet just increases that mind-set, which is why today we have billion dollar corporations who do nothing but try and stop hackers and spammers. Here’s where the responsibility part comes in. As developers, we need to try as hard as we can to prevent these kinds of attacks by first knowing about the vulnerabilities of the technology we choose to employ, and secondly we need to try as hard as we can to cover those vulnerabilities as best we can.

Identifying the pressure points

Specifically, the types of forms I’m talking about would include contact forms, account signup forms, and possibly even comment forms. Really, any form that sends outgoing mail has the same weaknesses. If we take a look at PHP’s Mail function and how it’s set up, we can see where we need to be careful. The Mail function signature looks like this:

bool mail ( string to, string subject, string message [, string additional_headers [, string additional_parameters]] )

Most of the parameters of this function just take string variables, but because of the way email works, PHP’s Mail function is actually a lot more powerful than it looks. The first three parameters are required, and usually wouldn’t provide any security risk, but it’s safe to check them anyways. The fourth parameter is the one that could possibly cause trouble if you’re not careful with it.

The additional_headers parameter is where you’d set addresses for the CC and BCC fields as well as any information about the content type of the email and weather or not it’s an HTML based email. If you don’t prevent against spammers from entering in data that utilizes the additional_headers variable, your form is now open to being used as an outlet for spam-bots.

Validating Input

One way to make sure that your forms don’t get used in un-intended ways is to validate the input against the known vulnerabilities. Specifically, protecting against any input that tries to modify the additional_headers variable is what we’re going to look at.

We’ll create a function that validates any of the input parameters against a set of known header commands that could possibly be used to send spam from your site.

function validInput($str)
{
    $ValidInput = true;
    $InvalidValues = array("content-type:", "charset=", "mime-version:", "multipart/mixed", "cc:", "bcc:");

    foreach($InvalidValues as $val)
    {
       if (strpos(strtolower($str),$val) !== false)
       {
          $ValidInput = false;
          break;
       }
    }

    return $ValidInput;
}

This simple function returns a value of true if the input $str is valid, and false if it contains any unacceptable strings. First we create an array of unaccepted strings called $InvalidValues. We then jump through each invalid value using a foreach loop and check to see if the $str variable contains any of the values. If any value is found, the $ValidInput flag is set to false and the loop is exited using the break command.

Now that we have the function in place, it’s just a matter of testing each value that you’ll be using in your Mail function against the unacceptable values.

if (validInput($Your_Email_Parameter))
{
    //Input is valid, send some email
}
else
{
    //Input is invalid, don't send anything.
}

Moving Forward

Where do you go from here? Well, you can further protect against spam-bots by logging each use of your mail form using a configuration file or a database, and only allowing a certain amount of email in a given time period for certain IP addresses. You could employ HTTP Referrer checking to make sure that the use of your form is from the location you intend it to be and you could also check the User Agent to make sure that it is actually set. (It’s common for spam-bots to have an empty User Agent value).

Each language (ASP, PHP, JSP, etc.) has its own version of a Mail function, and each of those functions have their own weak spots. There’s really no way to completely spam-proof your mailing forms though. Hackers and spammers are becoming increasingly creative in the methods they use to find, and exploit vulnerable forms. Hopefully as developers we can stay one step ahead of that creativity by doing what we can to secure our forms and stifle their efforts. Thoughts?

Posted in: Code, Web Development

« February 2006 »

Sun Mon Tue Wed Thu Fri Sat
   1234
567891011
12131415161718
19202122232425
262728    

Search this site

Latest Entries

Hot Topics