Defeating Form Spam

If you maintain any web site, you probably have a form of some sort where visitors can contact you. And eventually, you will start getting ‘form spam’, which is just what you think it is.

Since I have many web sites (it’s a hobby, with the optimistic theory that one of them will one day be worth millions), the forms on those sites get attacked. The mechanics of the attack are not important here – they are automated form submittals with links. The intent of the spammer is to get those links on your web site, so they can get revenue from the display and clicking of those links.

There are several techniques to block them. Catpchas – those squiggly words and letters – are one, hidden fields are another, but those can get bypassed. Even captchas are being hacked.

One technique I used in the past was to just rename the contact form page (and the ‘process the form’ page) filename, getting rid of the old file on the web host. That would usually buy me a couple of months. Hidden form fields might be another few months of protection. I don’t get many form spam submissions – probably because my sites are not well-read (hello to my three regular visitors).

Then I found another technique. This one has promise. It’s mainly for PHP-language based sites (although it could be modified for other languages), and you do need a bit of PHP programming knowledge. So here’s the basics (mostly for my own benefit, to make sure that I remember how to do it).

First step: create a new file called ‘response.php’ (assuming that you don’t already have a file like that). This looks like a promising name to a spammer; change it if  you wish. Inside that file, enter this line at the top of the page

 

<?php header(‘Location:http://www.formspammertrap.com/’);return; ?>

Make sure it is the very first line of the file. You can put other stuff in the file’s body area, if you want to further obfuscate things. But the main thing is that if a visitor (in our case, the evil form spammer) go to that response.php page, you will immediately get redirected to the site in the command. You can change the ‘location’ value if you want; just make sure it is a real page.

Upload that file to your host, and browse to it to make sure the redirect works.

Next step: edit your contact form page (or whichever page you want to protect). Insert this code just before the “</body>” (end body) code:

 

<script type=”text/javascript”>
var Clicked =0;
var C13379746183901= “”;

var C13379746183902= “”;
var FormName=”the-form-name”;

function CL() {
Clicked++;
if(Clicked > 1) { return; }
eval(“document.”+FormName+”.action='”+C13379746183901+C13379746183902+”‘”);
}
</script>

Replace ‘ the-form-name’ with the ‘name’ value used in your <form> command.  (Inside the ‘form’ code of your form, you have a “action” value. That is the page that processes your form.) Take that value, split it into two pieces, and place the two pieces in the C….01 and ‘C…02’ variables. Make sure you get them in the right order.

What that script does is put the two “C…” variables together, and puts them in the ‘action’ value in the form that is named ‘the-form-name’. That replaces the ‘action’ value in your <form> code with the real form processing page. (If your form page also does the processing, as in “action=’’ ”, just use empty values as the two “C..” variables.)

The third step is to put the fake form name (in our case ‘response.php’ as the ‘action’ value in the <form> code. This will be what the form spammer sees.

The fourth step is to have a required field in your form get this additional code inside the <input> code. Important: do not place this in the first field on the form, since that form field often gets ‘focus’ when you load the page. Also, if you use the same form as a function called by other pages, you will need to add that JavaScript code to the other pages too … and your authorized editor’ need to know that they must click in the field that has the ‘onfocus/onclick’ code, or they will be redirected to the phony page.

onfocus=”CL()” onclick=”CL()”

And the last step is to make sure your <form> has a ‘name’ parameter that is ‘the-form-name’ (or whatever you called the form).

Save your comment form page (make a backup copy of the old one first).

This is what happens when a real visitor fills out your form: when they get to the required field (the one with the ‘onfocus’ and ‘onclick’ code in the <input> statement), the CL() function will grab the two pieces of the real ‘action’ page and stick that in the ‘action’ parameter of the <form> code, replacing the ‘response.php’ fake page name that is in the code. So a ‘submit’ by a real person will get to the real form processing page. The form spammer, with his automated tools, won’t fill out the form normally, so the ‘onfocus’ and ‘onclick’ (both are required) will not happen, so they will use the ‘response.php’ fake page name.

Now, when I first saw this technique, I had to read through it a couple of times (perhaps I am a slow learner), but then it all made sense. We’ve used some JavaScript to replace the ‘action’ value in the form, and the JavaScript function is not executed unless a real person clicks in the required field.

Note that you may have some visitors that don’t have JavaScript enabled (usually, the paranoid types). For them, you just need to put a small notice just above your form:

<noscript>Note: JavaScript must be enabled to use this form</noscript>

You can use a bit of CSS to make that code stand out if you wish.

If you are already getting form spam, you might want to change the name of the contact form (and the processing page) to a new set of names. Delete the old name, and change the contact page value in any links elsewhere on your site. This will prevent the form spammer from using the old-unprotected form pages.

But the result of this technique should be a significant decrease in the amount of form spam that you get. And that’s a good thing!

(Added 22 Sep 2013: If you want more details, go to my Form Spammer Trap web site that uses the technique. That site is where form spammers will end up. And this post about it is more recent.)