On Sat, Jan 19, 2013 at 06:33:33PM -0600, Jimmy Hess wrote:
On 1/18/13, Matt Palmer <mpalmer@hezmatt.org> wrote:
Primarily abuse prevention. If I can get a few thousand people to do something resource-heavy (or otherwise abusive, such as send an e-mail somewhere) within a short period of time, I can conscript a whole army of unwitting accomplices into my dastardly plan. It isn't hard to drop
You can prevent this without cookies. Include a canary value in the form; either a nonce stored on the server, or a hash of a secret key, timestamp, form ID, URL, and the client's IP address.
Nonce on the server is a scalability hazard (as previously discussed). You can't put a timestamp in a one-way hash, because then you've got to hash all possible valid timestamps to make sure that the hash the user gave you isn't one you'll accept. You *can* put all those details into the form, then generate a HMAC (or symmetrically encrypt those details) to prevent tampering, but without server-side storage -- again, scalability hazard -- you can't prevent replay attacks (for as long as the timestamp is valid). The problem with this method, though, is that the only thing that stops the attacker from retrieving the entire chunk of data out of your form and tricking the client into submitting it is the client IP address. Now, you've got a decent idea here:
If the form is submitted without the correct POST value, if their IP address changed, or after too many seconds since the timestamp, then redisplay the form to the user, with a request for them to visually inspect and confirm the submission.
Which is decidedly more user-friendly than most people implement, but suffers from the problem that some subset of your userbase is going to be using a connection that doesn't have a stable IP address, and it won't take too many random "please re-confirm the form submission you made" requests before the user gives your site the finger and goes to find something better to do. I just realised that I may have been insufficiently clear in my original request. I'm not looking for *any* solution to the CSRF problem that doesn't involve cookies; I'm after a solution that has a better cost/benefit than cookies. Things that require me to worry (more) about scalability are out, as are things that annoy a larger percentage of my userbase than cookies (at least with cookies, I can say "you're not accepting cookies, please turn them on", whereas with randomly resubmitting forms, I can't say "please stop changing your IP address" because that might not even be the problem). - Matt