Is your website used for relay spam?
Saturday, 28 October 2006
Most websites have “contact forms”, which allow customers to get in touch with the website owners, without the owners necessarily having to reveal their contact email address. The customer typically fills in their name, email address and some message text. When the customer submits the contact form for processing, the server software then constructs an email message and sends it to the website administrator or owner.
Sometimes, that same server software also sends the message to lots of other people too and the website administrator won’t even be aware of the fact that their contact form is used to send spam. This is what’s commonly known as “relay spam” and it’s usually achieved through a trick known as email injection.
For instance, by adding a newline as well as the text “Bcc: user1@someotherdomain.com, user2@someotherdomain.com” to a website contact form, the attacker has now sent the email to an additional two users and the website owner will almost certainly be blissfully unaware. By manipulating the email headers in this way, the attacker can effectively turn any website contact form into a nice little open relay system.
One possible solution is to authenticate the form on submittal by detecting the presence of newlines and refuse to send the email, if they’re found in the name or email fields. Using PHP, we might do something like this:
// disallow newlines in the name form field
$_POST['name'] = isset($_POST['name']) ? trim($_POST['name']) : '';
if (eregi("\n", $_POST['name']) || eregi("\r", $_POST['name'])) {
die();
}
if (eregi("%0A", $_POST['name']) || eregi("%0D", $_POST['name'])) {
die();
}
// disallow newlines in the email form field
$_POST['email'] = isset($_POST['email']) ? trim($_POST['email']) : '';
if (eregi("\n", $_POST['email']) || eregi("\r", $_POST['email'])) {
die();
}
if (eregi("%0A", $_POST['email']) || eregi("%0D", $_POST['email'])) {
die();
}
Additionally, you might also consider checking that the form is actually submitted from the website, instead of some script kiddies computer:
$referer = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '';
$host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : '';
if (strlen($referer) == 0 || strpos($referer, "$host/") === false) {
die();
}
Keep in mind, however, that this check will potentially also block a small percentage of legitimate users, if they happen to be behind a misconfigured web proxy or corporate firewall.
|
I hope that didn't. But what is spam?