This article on how much CAPTCHA sucks mentions that Animoto used timestamp analysis to cut down on spam.
It includes a link to a jQuery tutorial on timestamp analysis. Basically, you use AJAX to have PHP set a cookie, use JS to add a hidden input to the form, and then (on submission) you compare the hidden input value with the cookie value. From the tutorial:
Checking the Form
test.php is the example PHP code used to verify the token
- Is the token [hidden input value] present?
- Does it match the timestamp when run through the md5() function?
- Has too much time elapsed?
...But it seemed really convoluted to me, for the following reasons:
My hope is that I actually have no idea how or why bots interact with HTML forms, and that I can now be corrected and educated.
The next two points seem to be guarding more against a spam-bot caching and reusing a form submit than against a given form submit taking too long after its enclosing page is loaded from the server. As you say, one would expect a spam-bot to be faster than an actual user at submitting a form, provided that the spam-bot follows the flow of requesting the form from your server and then submitting a response back. But not all spam-bots will follow that flow. Some might cache the page that your server sends (or the response that was generated for that page) for reuse over and over again. If they did that, then the timestamps/cookies give you a way to detect it.
But I really think the timestamps are unnecessary. I'd stick just with the token + JavaScript, using an approach roughly like:
So all the explicit timestamp nonsense goes away, because that is built in to the HTTP session. Very old sessions will expire, taking their tokens with them. You still filter out any spam-bots that aren't sophisticated enough to support JavaScript or cookies, and you defeat the use of cached URL's/form submits because step 6 ensures that no token can ever be used more than once. Basically the spam-bot is forced to go through the entire cycle of requesting the page from your server, executing the JavaScript, and submitting the form for each submission that it wants to make.