Based on a German article you can find here:
http://www.1ngo.de/web/captcha-spam.htmlI created some solution demos for FF.
In this article the author describes that the use of Captchas doesn't make sense because spammers will always find a way to make a code which is able to "read" the captcha picture and fill in the right code. Moreover he says that people with handicaps like being blind or other things like that are often not able to find a way to fill in a form which uses such methods of spamcheck. Even an audio method is not the right way because you can't be sure that the user's browser is able to play the file or maybe you have someone who is not able to hear.
But there's hope: There are much easier methods of checking a form for spam attempt, the author describes three of them in the mentioned article. I made a demopackage which uses all three methods in three forms, you can combine these methods and change the source like you want to make it harder for spammers.
The three methods:
1. Using fieldnames as traps
Spambots are not humans and so they try to find input fields which have names like "email" or "url" or similar things. So why not give spambots what they like to find?
This first method simply adds two fields to the form named "email" and "url" and they are labelled with "please don't fill in this field!". The user sees this and can react to this by simply leaving these fields blank. A spambot cannot, it can't read the label and if then it don't know which label belongs to which field (in the demo I named the label "lblemail" and "lblurl" but in a real form you should use a name which don't contain the fieldname).
The spambot would find the field, reads it's id (which is a number in FF like "ff_elem7599") and read it's name which is in this demo "ff_nm_email" and "ff_nm_url". The scriptkiddy is glad to find the text "email" inside the "good hidden" word "ff_nm_email" and believes this is the right field to fill in a spam email, same with url. The other fields are ignored - and if not, no problem, because the spambot already filled in these two not allowed fields, too.
In the "begin submit" piece now you simply test if these fields are filled and if yes, it must be a spambot (or a user who is not able to follow a simple hint...).
If you need fields for email or website then you can use cryptic fieldnames like shown in this demo form. A spambot cannot find out which fieldname belongs to which value because of these names. And - you can give the user a hint how to fill in these values like "please use the format 'website dot domain' instead of '
http://www.website.domain'" and the same with email. This special format can be simply tested with a validation script in Javascript and for security once again in PHP and can be changed to the right format with some simple string commands before being saved to your database table.
2. The time trap
Spambots usually are very fast so the "fill" a form within few seconds or microseconds and submits it. Often they use only a standard form they created themselves because they know the format of the form and don't need the form itself (so because of this it makes NO sense to use Javascript for testing, please use PHP in ANY case for testing a user input if security is necessary!).
Result is: Many spam submits in a short time or single submits in a short time.
So this method uses the time itself against the spammer: In the value field of a hidden input field (in the demo not hidden) with a cryptic fieldname (in the demo simply named "s", use a longer name) place the simple script which fills the value with a timestamp from PHP. As you see in the field when you open the form there's a numerical value which is this timestamp (following the PHP manual this is the number of seconds since 1970-01-01, 0:00).
If the user submits this form in a time lower than 10 seconds or longer than 15 minutes the form will be rejected (you can adjust these values in the "begin submit" piece). I don't think that a user is able to fill in two fields with website and email in a time lower than 10 seconds.
3. The input filter
The third method used here is a simple input filter. As spammers are only interested in coming to their website or mailing for Viagra or other such things the only real interesting values they want to submit are email addresses and websites. So you can use this filter method to check any of the input fields (two in the demo) for values which could be part of a link or an email. Possibilities:
<a href="www.website.com">
[url=www.website.com/index.htm]Website[/url]
http://www.website.com
spam@website.com
So you don't need complicate wordfilters but only simple things which shouldn't be part of an input field. That is html brackets, BB Code brackets, slashes, dots, @, texts like "url" or "href" or "http" and so on.
This third form uses a simple function which tests a text if it contains one of these things (you can add more like doublequotes, "=", "www" or whatever you like).
Every field is copied into a PHP array so it can be tested in a for loop.
4. More methods (not part of the package)
4.1 encrypting the timestamp
All these methods are combinable like you want and can be make more secure. For example: You could use an own algprithm for encrypting the timestamp so the spambot even don't know THAT it is a timestamp and decode it in PHP on submit.
4.2 using a two-page form
You can use a two form method where the first page of the form is only used for a few simple fields like "name" or "city" or whatever you like. Then use one or all of the spamtests described above for this first page and then send the values the user already filled in on the first page as parameter back to the same form and add the parameter to switch to the second page automatically like shown in the demo. Remember: One form is always one form, it doesn't make a difference how many pages it contains of, these are only hidden und displayed fields of the same form!
On the second page you can now add all other fields you want to use for your form because the first fields of the first page you set back to the user's value by filling them with "ff_setValue" to the original value (because the user can't see them so the form must fill it for the final submit).
Now the user can fill in the rest of the fields and on submit the fields of the first page are submitted, too. To separate the first and the second submit you could use another hidden input field which says which submit is used so page 1 will not spamtested again.
In the first submit all the fields of page 2 MUST be empty because the user cannot see them and therefore cannot fill them. A spambot would see ALL fields (because it reads the sourcecode of the form where is no difference between hidden and displayed fields) and so it would see all the rest of the fields. The spambot sees now fieldnames like "street" or "zipcode" and so on and would try to fill this, too. Your submit code can now test these additional fields of page two and check if it is the first submit and if yes then if these fields are empty. If not it must be a spamattack and so you can reject the complete form.
4.3 let the spambot "feel" good
You see, there are a lot of possibilities to reject a form before it is saved. In the demo I showed a page containing only the text that the form is not filled correct. You never should warn the user with "this was a spam attack" or "hacking attempt" or something like this. Spambots would check these texts and if there is text which shows that they was catched they will check the form more deeply to find a way.
You can use the above methods to give the spambots the "feeling" of successful submitting - because they won't check your code if the form is submitted correct. So you can trap all spammers which tries to fill in a form manually by giving them a feedback that all is correct.
In this method you could use the normal FF captcha image to let the form look like a "secured" form. Spambots crack this code easily and they are sure there spam is submitted - but if you use the above methods you make a more deeply check and decide if you save the values before displaying a "thankyou" page.
If you use the input filter method for example then you can test if there are not allowed contents in the input fields and in this case you don't save the values but display the "Thankyou" page. If the form contains correct values you save the values first and then display the "Thankyou" page. The spambot will not see any difference, even the normal user's won't see any because the saving only takes place on the server.
You only must make sure that the normal validation of the form is part of the Javascript check before submitting. So for example if you have an input field for "name" you can check the field if it contains a website address or an email and give the user a warning that this is not allowed.
The user who wants to fill the form will change the input and submit. The spambot thinks "hehe, I'm better than a simple Javascript validation, I submit the form without Javascript and so the value gets in the database!". But because of the additional spamchecks and the faked "thankyou" page the spambot "feels" good and thinks the spam is sent to the database and cannot find out if the values of the form are really saved.
These methods work very much better than any captcha because the normal user don't need to input complicate captchas and this is barrierfree for anyone - and the spambots don't know if they have success if they are not informed that the form was not submitted to the database.
Have fun with it!
Christian