Spammer Messes with My Headers

A few weeks ago, I mistakenly believed that I had closed a PHP mail form vulnerability that let spammers use my web server to send mail.

Another batch of penis enlargement and phentermine pitches were sent through my server last night, which I discovered when "rejected bulk e-mail" bounces found their way to me. A spammer exploited a mail script I had written that coded the recipient address like this:

$recipient = "info@ekzemplo.com";

I thought the script was secure because users couldn't change the recipient. As it turns out, there's another giant programming blunder in these lines of code:

$name = stripslashes($_REQUEST['name']);
$email = $_REQUEST['email'];
$subject = $_REQUEST['subject'];
$comments = $_REQUEST['comments'];

mail($recipient, $subject, $comments, "From: ".$name." <".$email.">rn" . "Reply-To: ".$email."rn");

As I learned last night, plugging user-generated fields into PHP's mail function leaves you susceptible to header injection, a technique that sends multi-line input to any field on a web form in the hope that each line will be interpreted as a mail header.

A spammer in Seoul, Korea, sent the following as the name field when calling the script:

to
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Subject: transcribe
bcc: charleselegb@aol.com

The script interpreted each of those lines as a real e-mail header, so charleselegb@aol.com received an e-mail with the text "2977b873a006112f1567c66ac468690a", which I'm guessing is encrypted text that identifies my server and script. The spammer's running software that crawls the web and hits forms, noting any that successfully send mail back to a test account. A Google search for that e-mail address shows Charles has been busy.

I've written a function that removes multi-line input -- identified by newline and return characters -- and prevents a spammer from defining multiple e-mail recipients:

function sanitize_request_input($input) {
  if (eregi("r", $input) || eregi("n", $input)) {
    $input = "";
  }
  $input = str_replace(";", " ", $input);
  $input = str_replace(":", " ", $input);
  $input = str_replace(",", " ", $input);
  $fields = explode(" ", $input);
  return $fields[0];
}

The function's called on any single-line text field contained on a form -- using it on multi-line textarea input would wipe out the text. The fix seems to have deterred Charles, who thoughtfully tried the exploit a few more times after I uploaded the new script, so I am again declaring victory over net abuse.

This is part two in an ongoing series.

Comments

Yeah this is getting annoying now. I have had to upgrade my PHPBB twice due to security holes, and now I am dealing with spammers going to the trouble to create accounts and quote random posts with random responses. I am going to write my own BB, something I have been putting off for a while, but now I have to step it up!

NOTE TO EVERYONE IN THE WORLD: Do not click on spam, nobody wants to give you money, your penis is small and will stay that way forever and you are not going to meet H0t babes online. We need to stop these spammers!

Yes, I've noticed exactly this thing going on with my "open-ended" PHP mail forms over the past month. You're far more generous that I am, though; I wrote my script to discard everything and exit if any newlines were present in single-line text fields.

It also helps to check for a "Content-Type:" string present in the textarea field.

Not posted the link to my site for obvious reasons, but here's a function I wrote in PHP to try and prevent spammers from doing this sort of thing with my own email form. Come to think about it though, I need to protect the Subject as well - which will mean a function similar to yours...

function VerifyEmailAddress($EMail){
// Uses a regular expression to deal with validation of an email address.
if (preg_match('/^[a-z0-9.-_]+@[a-z0-9.-_]+.[a-z]{2,4}$/i',$EMail) > 0) return true;

return false;
}

Yes, what a pain. I've now added to all of my php forms that send email a function that loops through all posted variables checking for "MIME-Type", "charset", and a bunch of other questionable wordings...

I have the same problem. My website got full and i could get email. I try to add another script to avoid this happen again. Hope it would work well.

if ($_SERVER['HTTP_REFERER'].=="www.yourdomain.com" || $_SERVER['HTTP_REFERER']=="yourdomain.com"){

mail($to, $subject, $message, $headers);

header("Location: sendmaildone.htm");
} else{

// do some record IP
header("Location: sendmaildone.htm?error");
}

Add a Comment

All comments are moderated before publication. These HTML tags are permitted: <p>, <b>, <i>, <a>, and <blockquote>. This site is protected by reCAPTCHA (for which the Google Privacy Policy and Terms of Service apply).