PHP mail exploit

From HostBaby Wiki

Jump to: navigation, search
  • FOR PHP USERS

If you are a PHP user, and have noticed your E-mails have been blocked by a host (aol, comcast, etc), this could be why.

In the past we've have gotten hit recently by spammers exploiting insecure calls to PHP's mail() function to blast out a bunch of junk (if any of you noticed when AOL stopped accepting any mail you sent for like a week, this is what caused it). It's an exploit known as "email injection."

Our techs have been going through our servers and fixing the ones they can find (and CHMOD'ing the files so you guys can't easily overwrite them with the broken versions in the future), but we doubt they can find every single one.

You're only at risk when you use a user-submitted variable in the 4th "headers" argument of the mail() function.. for example, say you have a FORM with an input asking for the submitter's email address, which you name "email".. then, on the PHP script the form submits to, you do something like:

mail("me@xyz.com", "subject", "body", "From: $email");

Spammers can use that to basically inject a whole new spam mail into your $email variable, overwriting your own specified info (aka the other 3 arguments). They can basically send whatever email they want to whoever they want. You can read a lot more details on this (and see some more examples) here: http://securephp.damonkohler.com/index.php/Email_Injection

What they've been doing to "secure" these is adding two lines of code for each variable being used in the headers argument of any mail() function:

if (strpos($email, 'Content-Type: ') !== false) exit;
$email = preg_replace('/[\n\r]+/', '', $email);

That first line checks for the string "Content-Type: " in the variable, and if it sees it, kills the whole process right then and there. The 2nd line (which most of the exploits probably won't make it to) then replaces all newline/enter characters with nothing (someone's email address should never take up more than one line). Obviously this code will need to go *above* the mail() function call to work.

If you do something like "From: $name <$email>", then you should also do the same two lines for the $name variable (etc, etc).

Personal tools