Preventing Contact Form Spam with PHP
Dec 10th, 2006
Gone are the days of posting email addresses on websites with “mailto:†for spiders to pick up. I typically use a contact form instead, or sometimes encode the email address with special characters. But a new problem has arisen with forms – form spam. From what I can tell, almost all of the spam appears to be from automatic programs trying to obtain links, i.e comment spam.
The messages typically have some random text with copious amounts href or [url] tags sprinkled in. What I have come up with is pretty simple, and could easily be defeated with a little ingenuity. However, it seems to do the trick in stopping the vast majority of contact form spam.
Since I am dealing with contact forms, I don’t expect any tags to be submitted through the form. I suppose it is possible someone would have a legitimate reason to submit a tag, but I haven’t seen it happen yet. Therefore, I check each field to see if any href or [url] tags exist. I also delineate fields that should be one line, like email and name, versus fields that can contain multiple lines, like a comment text box. I have noticed the spammers typically use new line characters, and then insert the link payload. A normal person would not have newline characters in an input textbox – so I don’t allow a form to go through if contains them. Enough of the talk, here is the code. It is for a simple form with two text inputs, email and name, and textarea, comments:
[php]
$singleLine = array("\\n","[url=","href=");
$singleFields = array("name","email");
$multiLine = array("[url=","href=");
foreach($singleLine as $needle) {
foreach($singleFields as $field) {
if(strpos($_POST[$field],$needle) !== false) {
echo 'There was a problem sending your email, please try again';
exit();
}
}
}
foreach($multiLine as $needle) {
if(strpos($_POST['comments'],$needle) !== false) {
echo 'There was a problem sending your email, please try again';
exit();
}
}
[/php]
It isn’t very sophisticated, but it seems to work…. One other thing, checking for the newline characters in general is good practice, especially for the email address. If you use php’s mail function, and put an unfiltered email address in the header, you are opening yourself up to email injection problems (where spammers use new line characters to add cc: and bcc: recipients to your email).
Happy spam blocking!
The messages typically have some random text with copious amounts href or [url] tags sprinkled in. What I have come up with is pretty simple, and could easily be defeated with a little ingenuity. However, it seems to do the trick in stopping the vast majority of contact form spam.
Since I am dealing with contact forms, I don’t expect any tags to be submitted through the form. I suppose it is possible someone would have a legitimate reason to submit a tag, but I haven’t seen it happen yet. Therefore, I check each field to see if any href or [url] tags exist. I also delineate fields that should be one line, like email and name, versus fields that can contain multiple lines, like a comment text box. I have noticed the spammers typically use new line characters, and then insert the link payload. A normal person would not have newline characters in an input textbox – so I don’t allow a form to go through if contains them. Enough of the talk, here is the code. It is for a simple form with two text inputs, email and name, and textarea, comments:
[php]
$singleLine = array("\\n","[url=","href=");
$singleFields = array("name","email");
$multiLine = array("[url=","href=");
foreach($singleLine as $needle) {
foreach($singleFields as $field) {
if(strpos($_POST[$field],$needle) !== false) {
echo 'There was a problem sending your email, please try again';
exit();
}
}
}
foreach($multiLine as $needle) {
if(strpos($_POST['comments'],$needle) !== false) {
echo 'There was a problem sending your email, please try again';
exit();
}
}
[/php]
It isn’t very sophisticated, but it seems to work…. One other thing, checking for the newline characters in general is good practice, especially for the email address. If you use php’s mail function, and put an unfiltered email address in the header, you are opening yourself up to email injection problems (where spammers use new line characters to add cc: and bcc: recipients to your email).
Happy spam blocking!
Posted In: PHP | 2 comments