For anyone who has posted a comment on my blog recently, you know that I was using a random Math equation to stop automated spamming via form submission. It worked amazingly well; I have only gotten a few spam comments (maybe 5) over the past 6 months or something. Having had such success with that, I thought I would take that idea and make even better so that the user pretty much doesn't have to do anything but submit the form.
This idea, like the previous Math idea, is based on the fact that a user will not see page elements hidden by CSS classes but a spam bot will see them. Since most spam bots do not render the page, they tend to submit all form fields present in the HTML. So, what we need to do is get the spam bot to submit form fields that a user would NOT submit. Furthermore, we need to do this without Javascript 'cause we can't depend on a user to have Javascript.
To get this to work, first I have to come up with a random value:
Launch code in new window » Download code as text file »
Then, in the blog comment form, I output this value as an encrypted HEX value:
Launch code in new window » Download code as text file »
Here, I am using the encryption key "SECRET_KEY_ONE" but you would make something up for your own form (this is a demo only).
The next part of this solution uses two sets of CSS classes for input fields. One set hides the input, the other set does nothing:
Launch code in new window » Download code as text file »
I am spelling out the CSS class names here so you can follow along, but in the actual solution, the CSS class names are much more random (so that spammers cannot guess things easily).
Then, on the ColdFusion side, I have a comma-delimited list of these two sets:
Launch code in new window » Download code as text file »
Then, I pick a random "good" class from the list of visible classes. I take this class and I randomly insert it into a list of bad classes (repeated twice for lower guessing probability):
Launch code in new window » Download code as text file »
At this point, the variable "lstAllClasses" contains all but one CSS classes that will hide any input field that it is attributed to. We also have the ONE good class (the only class in the list that shows an input field) in the variable, "strGoodClass". Using this full list of classes, I output a form submission button for each class:
Launch code in new window » Download code as text file »
Several points to see in the above code:
Ok, so what's with all this hubbub? The reason this works is that form submission button values are ONLY submitted as part of the form data if the user clicks on it. That means that the only one of the form submission buttons will be submitted by the user (since only one submission button is visible to the user).
Now that's all on the form side; let's take a look at the ColdFusion form processing side. This is the code I use during the form data validation:
Launch code in new window » Download code as text file »
Here I am getting the hidden form field value as well as the submit button value, decrypting them, and comparing them. Notice that I have to loop over the FORM collection to get the dynamic submission button keys. We only decrypt the first value that we come across. However, we keep track of the number of dynamic submission values passed in. The idea here is that only a SPAM bot would submit more than one and a standard user would submit ONLY the one that they clicked on.
I only put this into effect this today, so I don't know how effective it is, but so far no spam has gotten through (except for three comments that got posted in the short time while I was working out the kinks). In order for a SPAM bot to circumvent the spam protection, they would either have to decrypt both the form values or randomly submit the correct form button. Since the de-spam value changes every page run, this becomes unlikely. I suppose the spam bot could submit the form data multiple times with different form fields excluded... but that's a problem I will tackle when I get to it.
So now, no more math questions. No more CAPTHA text. The only down side is the user has to physically click the submit button... but that's not so bad, is it? Oh and their browser has to support CSS... but if it doesn't do that - yikes!!!
Download Code Snippet ZIP File
Comments (3) | Post Comment | Ask Ben | Permalink | Other Searches | Print Page
You write:
<tt>The only down side is the user has to physically click the submit button... but that's not so bad, is it? </tt>
Well, kinda. You can submit forms by hitting "enter" in just about any field other than a textarea. I think there are enough keyboarders (like myself) who would submit forms like that.
Does the user get any indication that their entry was not accepted? I waffle on whether they should or not. If you tell them, the spammers can fine-tune, which is bad. If not, you end up ignoring your users, which is far worse -- unacceptable for many projects.
Thoughts?
Always listen to experts. They'll tell you what can't be done and why.
Then do it.
Robert Heinlein (1907 - 1988)
Posted by Fellow developer on Feb 1, 2007 at 10:36 AM
Fellow developer, I completely agree with you. This was one implementation and is, in fact, not the one that I use any more. I use the keyboard quite heavily and this method was hurting my usability (let alone anyone else's).
Posted by Ben Nadel on Feb 1, 2007 at 11:32 AM
What implementation are you using instead?
Posted by Deborah on May 24, 2007 at 10:03 AM