Preventing Contact Form Spam with PHP

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();    
    } 
}

?>


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!

2 Responses to “Preventing Contact Form Spam with PHP”

  1. Andy Ford Says:

    Another method that I think I picked up from the SitePoint forums…

    Add an extra form field
    Name it something enticing (to spam bots) such as “comment” or “url”
    Use CSS to make the form field hidden
    Any form submissions with this field filled-in are assumed to be spam

    …not the most advanced method, and certainly not foolproof. Also not good for users with CSS disabled, but it’s a technique worth considering

  2. Administrator Says:

    That’s a good one. I have tried having a hidden form field, so that you don’t run into problems with CSS disabled (as you mention), but the bots only fill it out a small percentage of the time.

    UPDATE: The code above should be “stripos” instead of “strpos”. A spammer started getting through because his “HREF=” was in caps, and strpos is case sensitive.

    My next step is to create a database, monitor comment spam and start blacklisting top level domain names. The spammers usually use sub-domains or keyword rich urls of their domains, so if you prohibit that domain from ever appearing in a comment field, it will reduce the spam. Of course it wont block a domain until I blacklist it. But, by using it across many different sites it would be more effective.

Leave a Reply