Since CAPTCHAs, securitywise, apparently are to be regarded as “rate limiting only“, combined with the fact that, usabilitywise, CAPTCHAs, er… well… you know… suck, I wonder: why not do rate limiting instead of CAPTCHAs?
But then: how could that work?
Suppose: you have a page where users that forgot their password would enter their email address to receive a ‘password reset’ link. You want to avoid users getting spammed in your name by people, or bots, submitting the ‘forgot password’ form repeatedly, just for fun. So you want to rate-limit it to, say, max 1 request per hour.
The GET request returning the form that would issue the POST request triggering the email sending, could set a cookie, a header, or a hidden form field with a token identifying the request. The POST handler should then decline any request without the token (and log it as an attack). Token forgery is avoided by encrypting the tokens when issued, with a key only known to the server.
The POST handler records the client’s IP address in a database, together with the timestamp, invalidating any subsequent requests within the next hour. Requests exceeding the rate limit can get a 429 Too Many Requests response status.
To prevent token reuse, and to protect against POST requests from spoofed IP addresses, tokens include the client’s IP address, and a timestamp – every new POST request has to be preceded by processing the response to a GET request from the same address. The timestamp should at least be after that of the last recorded request. You might even have the tokens time out after like 1 minute.
These rate limiting tokens in fact seem quite similar to CSRF tokens. A big difference is that for rate limiting, we have to save data server-side about previous requests, whereas for CSRF prevention, all the verification data can be contained in the POST request itself. Which is quite a shame in some way, since I started out all this by thinking I could effectively store (encrypted) CAPTCHA solutions client-side, instead of in the database… but leaving CAPTCHAs altogether sounds equally appealing, if not more!