Home > Security > Email injection exploit through a PHP contact form

Email injection exploit through a PHP contact form

December 15th, 2005 Tony Leave a comment Go to comments

hax0r
Earlier this week I became aware that one of my domains was blacklisted on SpamCop. Ouch. My first thought was that it was no big deal. I’ve often been blacklisted by Yahoo and others simple because I send out opt-in emails (very tame stuff like order confirmations). Its a pain but you typically just have to prove that you aren’t a spammer and you’ve just tripped a sensitive filter.

Unfortunately after much digging through logs I realized this wasn’t the case. I was the victim of a rapidly spreading exploit known as email injection that took advantage of my super secure, locked down tight as a drum code. :)

Heres how email injection works:
A would be spammer (the email variety, not a search engine spammer) googles for an email contact form. If they find a ‘contact us’ page that is vulnerable they manipulate the form fields to add/change email headers. They accomplish in much the same way a hacker would perform SQL injection or website search results injection. By entering hexadecimal characters in the form field they are able to add carriage returns and spaces. So the following string entered in a form field such as “Your Email”:

“sender@somesite.www%0ACc:victim@victimsdomain.xxx%0ABcc:victim2@victimsdomain.xxx,victim3@victimsdomain.xxx”

will result in a carbon copy of the email being sent to victim@victimsdomain.xxs and a blind carbon copy being sent to victim2@victimsdomain.xxx and victim3@victimsdomain.xxx

As you can see it is easy to manipulate the headers and as a result you can get really fancy and change the subject of the email, mime-type, sender, and the body of the message. The end result is an email open relay. I grabbed a couple of IP’s that were used to POST the data and sure enough they were listed in my database of current open proxies. SecurePHP has a full rundown of the examples.

To secure your email contact form, check each form field against this function. If any one of them fails you can report an error or just silently bail on sending the email. I don’t believe that its necessary to run this check on the body field of the message as this doesn’t have any effect on the headers.

function containsInjectionAttempt($input) {
if (eregi(“\r”, $input) ||
eregi(“\n”, $input) ||
eregi(“%0a”, $input) ||
eregi(“%0d”, $input) ||
eregi(“Content-Type:”, $input) ||
eregi(“bcc:”, $input) ||
eregi(“to:”, $input) ||
eregi(“cc:”, $input)) {
return true;
} else {
return false;
}
}

The problem even exists for the popular CMS Drupal. I can’t tell from this bug report if its been fixed yet but it appears to still be an open issue so you may want to run a test on your own site if you are running Drupal.

Categories: Security Tags:
  1. Hugo
    February 7th, 2006 at 10:44 | #1

    Hi Tony,

    have you actually tried to test whether the
    0×0A injection business works?
    I read the same article on damonkohler.com
    and tested my own form, but as far as I can see,
    neither %0A or 0×0A (or with 0×0D etc.)
    actually created a newline, so the attack
    wouldn’t work.
    Might be hosting-specific or something I don’t know..

  2. Chad
    April 5th, 2006 at 00:53 | #2

    The bcc: is probably redundant since cc: should cover both :)

  3. Kat
    May 25th, 2006 at 11:03 | #3

    And if just verify that the from-field is a valid email, with the regex like this
    eregi(“^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$”, $from)?

    Thank you ;)

  4. Steffen
    August 19th, 2006 at 07:27 | #4

    i hae to hack a homepage coz they deleted our and i dont know how i can hack there homepage… i need help :P when you see this mail , i try to hack the page but im sure it wont work ^^ … http://www.ts-gamers.de.ki and http://www.ts-gamers.de.vu hack these homepages pls … THANK YOU

  5. MB
    September 15th, 2006 at 03:35 | #5

    Why not just use the filter solution used in the SecurePHP article? First, urldecode the field, then eregi for \r or \n. If either is present, then deny. Won’t this catch any hack attempt to added header fields?

  6. jean
    November 20th, 2006 at 04:26 | #6

    I tested a form using the hex characters and succeeded in sending additional copies of mail in this fashion.
    The body of the message is not necessarily secure – I added %0a%0dcc:name@domain.com at the very end of a message and succeeded in sending a message.
    I decided to remove ‘:’s and replace @ with .AT. for a nervous client in addition to checking for \r, \n, etc. etc. and so far it is holding up very well.

  7. June 21st, 2007 at 02:29 | #7

    Hi. I used your code in my site and it works fine except for cc: . When I tested out cc: in my contact form it always gives me a 406 error, with any of the other situations such as to:, it works as expected and it leads through to my own planned response (please re-enter your e-mail without dangerous, possibly spam causing strings such as to:). any ideas?

  8. Alex
    June 28th, 2007 at 16:44 | #8

    what about limiting the form field I mean a simple 15 letter limitation should basicly limit most of the problem

  9. Chik
    August 30th, 2007 at 13:01 | #9

    Thanks… but I’m not experienced enough with php to know how to implement these suggestions safely. Can anyone recommend a solid script that I can buy which will protect against injection?

  10. DrTebi
    October 1st, 2007 at 17:53 | #10

    I know this article is a bit outdated, but for those checking it out and running PHP 5 >= 5.2.0, check out the Filter Functions:
    http://us3.php.net/filter