A Good Form Spam Prevention Technique
Spammers have robots that go look for forms. When a form is found, the robot sends information about the form to home base.
Then, robots dedicated to spamming individual forms are let loose, generally from various IP addresses so they can't be blocked that way. Every so often, maybe daily or a few times per day, or maybe only weekly, the robot comes around and submits an advertisement through your form.
There are CAPCHA mechanisms designed to prevent robot submissions by requiring the form user to prove they are human. It can be dehumanizing to provide that proof. Still, if a person needs to send a message and the form has a CAPCHA, using it is required.
CAPCHAS are becoming ever more sophisticated and ever harder to navigate in order to prove ones humanity.
Probably many website feedback forms are abandoned because the people who would have sent a message are daunted by the hoops they have to navigate. My thought is that only forms that a person must use aren't frequently abandoned, like login forms to sites a person needs.
For feedback and other forms that site visitors aren't required to use, visual CAPTCHA can be a killer.
However, there are behind-the-scenes and invisible techniques that can be implemented to determine if the form "user" is actually a robot. Because human form users aren't inconvenienced, the form is less likely to be abandoned.
For those that don't have Master Form V4, which has form spam robot detection built in, here is a technique that can work very well.
Information located in a div
tag can be used to prevent form spam. Because div
is a non-form tag, spamming robots are unlikely to realize its purpose.
A hidden form field has a decoy value. JavaScript updates the decoy value with the content of the div
tag when the form is submitted.
(The div
has CSS declaration display:none;
to make it a non-display div
.)
In order to detect the spam prevention code, a spammer's robot would need to (i) recognize that the content of the non-display div
tag will be used as the hidden field value or (ii) it needs to parse and run JavaScript like a browser. Neither is likely.
The form processing software or web page, where the form is submitted to, responds with a 403 Forbidden code unless the hidden field's value is identical to the content of the div.
(The Willmaster Blog and the Library both have articles describing other form spam prevention techniques. Do a search for "form spam" from any Willmaster.com page and you'll get a list of them.)
How This Form Spam Prevention Works, Step-By-Step
When the web page with the form loads into a browser (or into a robot's manipulation area), these two things are present:
-
A non-display
div
is somewhere on the page with custom content. -
A hidden field is somewhere within the form with a decoy value.
When the form's submit button is clicked or tapped (which a robot doesn't do, having neither mouse nor finger), these two things happen:
-
JavaScript copies the content of the
div
into the value of the hidden field. -
The form is submitted to the form processing software or web page.
When the form processing software or web page receives the submitted form information, it does one of two things:
-
If the hidden field doesn't exist or its value isn't identical to the non-display
div
content, it responds with a 403 Forbidden code. -
The hidden field's value is identical to the non-display
div
content and form information processing proceeds normally.
Either —
Or —
Now, seeing how it works, let's implement it.
Implementing Form Spam Prevention
There are two steps to implementation.
-
The web page with the form. The web page has the JavaScript, the non-display
div
, and the form. The form has the hidden field and also an onclick attribute for the submit button or image. -
The form processing software or web page. This is where code to spot spamming attempts is located.
We'll do each section separate.
Implementing at the web page with the form.
Here is a complete example implementation for the web page with the form. Notes follow.
<div style="display:none;" id="div-spot">glory</div> <form method="post" enctype="multipart/form-data" action="/script.php"> Email <input type="text" name="email"> <input type="hidden" id="some-place" name="some_place" value="classified"> <input type="submit" value="Submit Button" onclick="return UpdateTheHiddenField()"> </form> <script type="text/javascript"> function UpdateTheHiddenField() { document.getElementById("some-place").value = document.getElementById("div-spot").innerHTML; return true; } </script>
The above example code has three sections, with a blank line between each: (i) non-display div
, (ii) form, and (iii) JavaScript.
Some information will need to be duplicated from the non-display div
and the hidden form field to the JavaScript. And some will need to be duplicated in the form processing software or web page.
To keep items separate and easy to understand, colors are used. To avoid having to use too many different colors, id values will be underlined and the rest not underlined.
Here are notes for each of the three sections.
The non-display div
The non-display div
is the first of three sections in the above example code. Each section is separated with a blank line.
Its id value div-spot is duplicated in the JavaScript (the third section, addressed further below). And its content glory is duplicated in the form processing software or web page (even further below).
The non-display div
may be placed anywhere in the source code of the web page.
The form
The form has two fields to notice, the hidden field and the submit button.
The hidden field's id is some-place and is duplicated in the JavaScript (see next section). The hidden field's name is some_place and is duplicated in the form processing software or web page (further below). Note that the hidden field's value can be anything; it's just a decoy.
The submit button has an onclick attribute that returns the value of the JavaScript function UpdateTheHiddenField(). The reason it's told to return a value is to force the JavaScript to run completely before the submission process is started.
The Javascript
To copy the non-display div
content into the hidden field's value, the JavaScript function UpdateTheHiddenField() references the non-display div
id div-spot and the hidden field id some-place. If either is changed, it needs to be changed accordingly in the non-display div
or hidden field.
The JavaScript can be put anywhere in the web page. Immediately above the cancel </body>
tag would work.
Implementing at the form processing software or web page.
Here's the PHP code to put into the form processing software or web page. Notes follow.
<?php if( empty($_POST["some_place"]) or $_POST['some_place'] != "glory" ) { header("HTTP/1.0 403 Forbidden"); exit; } ?>
The some_place (both places in the code) is the same as the hidden form field's name value. If one is changed, all need to be changed accordingly.
The glory is the same as the non-display div
content. If either is changed, both need to be changed accordingly.
Where to put the PHP code.
Important: Make a backup of the web page or software file before any changes are made.
If the form submits to a web page (like Master Form .PHP does), paste the code at the top of the web page source code.
If the form submits to stand-alone PHP software, it depends on the software. You'll want to put the PHP code where it will be run before anything else. For most software, that would be at the top of the file that the form submits to.
If uncertain where to put it, try it at the top of the file. And if that doesn't work, perhaps the programmer of the software can help, or the place where you downloaded it from. If needed, I may be able to help with a bit of custom programming.
(This article first appeared in Possibilities ezine.)
Will Bontrager