Join 3,366 readers in helping fund MetaFilter (Hide)


Help me defeat the spammers!
December 4, 2006 9:58 AM   Subscribe

Is this a spammer trying to circumvent my website "contact" button?

Due to assloads of spam, I recently switched email addresses and switched from offering my email address on my website (as an image, which got harvested anyway) to a form that passes the message to a simple PHP script.

This morning I saw three emails. This was the content (yes, complete with garbage shown here; identifying features removed):

up to 10 added solution can be called ham water added . inally, ham and water product refers [random hex/numbers] > Reply-To: cure Content-Transfer-Encoding: quoted-printable Content-Type: text/html Subject: by the end of uly bcc: [scum] up to 10 added solution can be called ham water added . inally, ham and water product refers [random numbers] Date: Mon, 04 Dec 2006 04:12:39 -0800 Subject: [INQUIRY] [nonsenseaccount@[mydomain].com [nonsenseaccount]@[mydomain].com

Is this an attempt to get a bounce back to him with a real address? I'm assuming the exploit didn't work, as I haven't seen any real bounces in my inbox.

In one of the variations I saw this in the Subject field: "Content-Transfer-Encoding: 7bit Content-Type: text/html Subject: use bcc: [spammer]".

I don't know if anyone here has PHP experience but here's the script I'm using (HTML stripped out so as not to confuse MeFi). If anyone sees any exploitation issues please let me know.

$to = "[our address]";
$username = $_POST['cc1'];
$email = $_POST['cc2'];
$subject = "[INQUIRY] " . $_POST['cc3'];
$message = stripslashes($_POST['cc4']);
if ( ($username == "") || ($email == "") || ($subject == "") || ($message == "") ) {
echo(" Could not send message... required fields were left blank. ");
die(); }
$headers = "From: \"" . $username . "\" < . $email .> \r\n" .
"Reply-To: " . $email . "\r\n" .
"Date: ".date("r"). "\r\n" .
"Subject: " . $subject ;
mail( $to, $subject, $message, $headers );
echo ("Thanks, we will reply to your message within about 24 to 48 hours.");
posted by zek to Computers & Internet (9 answers total)
Google "PHP email header injection" for more information.

Note that if the submitter sends you information that has, say, embedded carriage returns/linefeeds in it, they can add extra headers to your email, such as CC: or BCC: headers. What if the submitted $_POST['cc2'] variable looked like this:>[carriagereturn][linefeed]

Wouldn't your script then cheerfully send mail to you, BCC:ed to every one of those people? Wouldn't your script spam them, in other words?

The exploiter is perhaps messing it up slightly. After all, he doesn't know exactly how your script is written, so he has to try a few different things. But that's what he's trying.

You need to do a lot more to those $_POST fields that you receive from the user before you can trust them enough to use them in constructing an email.
posted by jellicle at 10:19 AM on December 4, 2006

You're setting the $to variable in your script, so no mail sent from that form can possibly be addressed to anyone but "to". The spammer may be simply emailing random [nonsenseaccount]'s at your domain and hoping one gets through.
posted by null terminated at 10:19 AM on December 4, 2006

Most delivery-checking exploit attempts I've seen don't include any sort of spammy filling - they're usually just one-liners to let them know they can bounce mail through your script.

This is probably just some auto-bot taking a poke at whatever your FORM ACTION= points to. Or, if the page is named something generic, like email.php, it could be trying out an exploit for another known email.php script.

Personal experience has shown that spammers will POST to anything they can, just because there's probably someone on the other end. This looks more like that, as opposed to a can-I-spam relay check.

Adding a lightweight CAPTCHA like "What's X+Y" into the process probably wouldn't hurt ...
posted by bhance at 10:23 AM on December 4, 2006

They're probably trying to exploit it to relay SPAM. These types of contact forms are often quite insecure and easy to manipulate this way. I've had a PHP contact form that over time I've added various measures to to both ensure that it can't be used to relay anything, and to mostly cut off the attempts before they end up in my mailbox
function safe( $name ) {
   return( preg_replace(array( "@\r@i", "@\n@i", "@%0a@i", "@%0d@i", "@Content-Type:@i", "@bcc:@i","@to:@i","@cc:@i" ), "", $name ) );
This last one is especially important, since failing to do so can allow the users of your form to insert their own headers.
posted by Emanuel at 10:24 AM on December 4, 2006

You might want to take a look here and here. And, no, I still haven't got round to doing anything about it ;o)
posted by jontyjago at 10:40 AM on December 4, 2006

Yeah, as jellicle points out, your script is *insanely* insecure from the standpoint of being able to be used to send spam. Spammers will find forms like yours, experiment in as many ways as they can to send a message back to themselves (so they can prove that your form is vulnerable), and then use it to send metric assloads of spam out. What you're seeing is their attempts to do this. In the one you quoted, they were attacking your message ($message) field; there were probably others attacking each of the other fields to see which were vulnerable (e.g., would allow them to inject headers and send spam).

Fundamentally, you shouldn't write contact forms in PHP unless you know what to do to prevent this. I'm not saying this to be denigrating, I'm saying this to prevent you from becoming a spam farm unknowingly and find that your ISP has shut down your access entirely.
posted by delfuego at 12:12 PM on December 4, 2006

I do several things to filter out header injection emails: I error out if any of the fields contain certain characters, as Emanuel points out. I use a CAPTCHA and I check the referer for the posted form. If it's not from my domain, I error out.
posted by tippiedog at 1:39 PM on December 4, 2006

Ive been getting the exact same stuff from my own website. I'm gonna pull the form when I get home.
posted by gergtreble at 2:54 PM on December 4, 2006

I'm not an expert, but I use preg_match to look for Bad Stuff and I also use a session token to ensure the submitted info came from my form. I also write to the htaccess file and deny from offending IPs (like that really does much, but, still).

So, use the PHP session token to prevent your form from being used on a remote server, and use some regex to check the fields being submitted and strip out dangerous characters. The safe function above is a fine way of doing so.
posted by maxwelton at 4:51 PM on December 4, 2006

« Older Homebrewfilter: why do clear b...   |  after many years in new york, ... Newer »
This thread is closed to new comments.