Contact Form Spam Protection

May 31, 2023 articles, code

Contact form spam is almost as bad as straight email spam. As a developer, I’ve tried many methods on how to help cut down on the spam. Today I am going to share with you a technique that actually works almost 100% on it’s own and since implementing it, works better than captcha!

Jump to the juicy parts

The traditional methods of fight contact form spam are:

CAPTCHA (Completely Automated Public Turing Test to Tell Computers and Humans Apart):
CAPTCHA presents users with a challenge that is easy for humans to solve but difficult for bots. Common CAPTCHA types include image recognition, math problems, or simple puzzles. Implementing CAPTCHA on your contact forms helps ensure that only genuine users can submit the form, significantly reducing spam.

Honeypot Technique:
The honeypot technique is an invisible field added to the contact form that is meant to be left empty by human users. Bots, on the other hand, typically fill out all fields. When the form is submitted with the hidden field filled, it can be flagged as spam and rejected. This method is effective because bots cannot easily detect the hidden field, making it a simple yet efficient way to filter out spam submissions.

IP Address Blacklisting or Keyword Blacklisting:
Implementing IP address blacklisting and rate limiting measures can significantly reduce spam submissions. By monitoring the IP addresses of users submitting contact forms, you can identify suspicious activity and block known spam sources. Additionally, setting up a keyword blacklist can keep common spammers from you inbox.

While all these techniques work to some degree, non of them really stop the automation. There are two types of bots. There are the source code bots, they either use tools to scan for certain form elements and fill in all the forms and use code to submit the form. Then there are headless browser bots. There are using a browser type code base interfacing with the website as if it were a real human. Again filling in form elements and clicking the submit button.

Enter JavaScript Cloaking

In 2015 I wrote a WordPress plugin called Cloak Front End Email. The basis was simple, JavaScript Obfuscation. Now at the time people were doing things like email (at) domain (dot) com. This format is a bad user experience, as the human has to translate and actually retype the email address. The other method was encoding the email then using JavaScript to decode it. Which is a valid method and maybe a more simpler version of what I did. My method was to actually hide the elements in the source code all together and use JavaScript to inject it into the page. This meant the email was not getting leaked in the source code, not even as encoded version. A more secure method in my opinion. And I was using the same ideas and techniques that Cloudflare uses for their own email cloaking.

Here is a simple code example of how you can implement this into a contact form. Of course you will need complete access to the form in order to manipulate the code base.

First the JavaScript:

jQuery(document).ready(function() {
  if(/PhantomJS/.test(window.navigator.userAgent) 
    || /SlimerJS/.test(window.navigator.userAgent) 
    || window.document.documentElement.getAttribute('webdriver') 
    || navigator.webdriver)) { 
    console.log( 'Headless environment detected.' ); 
  } else {
    var cloakform = '<input type="submit" value="Submit" />';
    jQuery( ".cloak-form-btn" ).html( cloakform );
  }
});

The first section is detecting the most popular headless browser default user agents. This is important as it will stop the submit button from being active and break the headless browser’s ability to actually submit the form. Then we just inject the standard submit button at the bottom of the form via JavaScript.

Next the HTML:

<form method="POST" action="/action_page.php">
  <label for="fname">First name:</label><br>
  <input type="text" id="fname" name="fname" value="John"><br>
  <label for="lname">Last name:</label><br>
  <input type="text" id="lname" name="lname" value="Doe"><br><br>
  <div class="cloak-form-btn">Please enable javascript.</div>
</form> 

That’s it, pretty simple.

I have started implementing this technique into my contact forms and so far it’s cut out 99.5% of the spam. Now if a human is actually taking the time to submit the form you can not ever stop that. And in the case of bots using an API to submit the form, then this isn’t going to protect you. That’s where the .5% comes into play. But overall I don’t even need captcha’s anymore with this method.