It has become apparent that spammers are getting even smarter than we take them for. Rather than abuse open relays, which are almost non-existent, these scum-of-the-earth ‘traders’ are now abusing contact forms.
However, the problem isn’t necessarily that they are attempting to use the contact forms. The problem that exists is that the average coder with little or no understanding of security issues can create a contact form for their website which can act as an open invitation to spammers.
The Problem
Lets take a quick look at a sample of code:
PHP:
-
$to = ‘contact@domain.com’;
-
 $subject = $_POST[“subject”];
-
 $message = $_POST[“message”];
-
 $headers = “From: “.$_POST[“from”];
-
 mail($to,$subject,$message,$headers);
A simple enough script you might think. It takes in the user’s input, and then sends the email using PHP’s mail() function. As we’ve already defined the ‘To’ field, surely we’re safe from it being sent to someone else? This is where people get caught up. What happens in the above code is that the user supplies their own email address, which is then placed in the From:
header, and possibly a Reply-To:
header as well. An unscrupolous user can easily insert other headers into the $_POST[“from”] variable which are then inserted into the email, and is then well on your way to abusing this mail script and getting it to send the email to multiple recipients. Just how possible is this? One way is to create a separate form and submit it to your mailer script:
<form action="http://www.yourdomain.com/mail.php" method="POST">
To: <textarea name="to"></textarea><br />
Subject: <textarea name="subject"></textarea><br />
From: <textarea name="from"></textarea><br />
<textarea name="message"></textarea><br />
<input type="submit" value="Send">
</form>
Entering the following to the From textarea will result in it sending the email to an unsuspecting recpient:
test@domain.com
Bcc: another@user.com
Simple really. Additional BCC addresses can be separated by commas. You could check for the HTTP Referrer on the mail.php script, but that is way too easy to forge. The correct way to overcome this is to correctly validate your input, ensuring that what was entered is exactly what you want.
Validate, Validate, Validate
Input validation is very easy to do, and is the one thing that should always be in the fore-front of your mind. For the contact form, the correct thing to do is to validate all your input. I found a fairly decent validation routine on the PHP website:
PHP:
-
/**
-
* Check single-line inputs:
-
* Returns false if text contains newline character
-
*/
-
function has_no_newlines($text)
-
{
-
  return preg_match(“/(%0A|%0D|\n+|\r+)/i”, $text);
-
}
-
-
/**
-
* Check multi-line inputs:
-
* Returns false if text contains newline followed by
-
* email-header specific string
-
*/
-
function has_no_emailheaders($text)
-
{
-
  return preg_match(“/(%0A|%0D|\n+|\r+)(content-type:|to:|cc:|bcc:)/i”, $text);
-
}
We can further validate our data and check that fields that are used to enter Email Addresses only contain valid characters. A simple google search for email regex patterns will bring up a wealth of information. RegexpLib is a good site to use as a base, however, they usually require minimal modification to work with preg_match(). Here’s a basic regexp by Rob Eberhardt to check an email address:
PHP:
-
if(!preg_match(“/^[A-Z0-9._%-]+@[A-Z0-9.-]+.[A-Z]{2,4}$/i”,$_POST[“from”])) {
-
//email address is invalid
-
die(“Invalid Email”);
-
}
And there we have some basic input validation designed to avoid email header injection. You might think ‘Well, what’s the point?’ In real life, if your contact form script gets abused by spammers, chances are your hosts will suspend and/or terminate your account, as once it starts sending out thousands of emails, it can quickly bring a server to a halt. Furthermore, the IP of that server can get blacklisted resulting in regular emails being blocked. So the sensible thing to do would be to validate your input, and save everyoone the hassle of dealing with spammers.
Taken from jellyandcustard.com
You must be logged in to post a comment.