Daniel,
I have a similar spam-detection approach that has been in place since last year. I can share what I have seen.
Session based tests: Checking the time it takes someone to fill out the form and checking that the user comes from the right page have been very reliable checks, though somewhat fraught with difficulty. In your case, forcing users to have modern, javascript enabled browsers might be your best option. And it seems like it's becoming a more accepted practice, I guess, right? I don't really know..
Content based tests: Another two fairly helpful practices are to check that form fields contain different values and that no more than a specified number of URLs have been entered. Spammers almost always seem to stick the same trash URL into every field. However, these checks aren't nearly as good as session-based checks.
Our spam-detection heuristic has a few other checks, in addition to the ones above:
- Basic regex injection tests - bare-bones, but I can share if you are interested
- Spam Content - pretty useless - a simple library constructed mostly by hand
- Banned IP Address - also pretty useless..
Some numbers from our heuristic over the last year or so. Total failed tests= 83,356
- Failed Injection Test = 54 (0 failed this test and no other tests)
- Failed Too Many URLs In Input Test = 18,935 (2396)
- Failed Spam Content Test = 3673 (46)
- Failed Hidden Field Tampering Test = 60,295 (1479)
- Failed Dubious Time Elapse Test = 64,430 (17,126)
- Failed Invalid Session Test = 28,706 (140)
- Failed Fields Contain Same Values Test = 167 (49)
- Failed Banned IP Address (not implemented) = 0 (0)
I don't want to post too many details about exactly what our criteria are, but if you are interested I'd be happy to share code.
-Ben