[thelist] Modern browsers and preventing double form posting

Lee Kowalkowski lee.kowalkowski at googlemail.com
Wed May 9 12:12:51 CDT 2012

On 9 May 2012 15:23, Bill Moseley <moseley at hank.org> wrote:
> Ignoring Javascript for the moment, I have tools I have used for a very
> long time to prevent double-posting of forms (url-encoded and form-data
> type forms).  It simply creates a unique token each time a form is
> rendered.   And along with that, each time a form is posted the post must
> include a token AND I must be able to atomically delete that token (it
> exists and only one process can remove it.)  The tokens tend to have a life
> of a few hours, IIRC.
> Another thing I do after each successful post is issue a redirect.
> Now, on one application I noticed that the testing of the token on form
> submission was disabled, which was a concern.  But, then I started to test
> the app and was unable via Chrome, Safari, and IE8 to even generate a
> double-post.

I'm not sure double-clicking is even relevant, that's just a classic
example, and a double-click is treated as a single event by most
operating systems / browsers.  The point is not even to prevent
duplicate posts, but to preserve the integrity of the data, usually
via some form of locking, usually optimistic (1st write received

Other techniques may be feasible that your solution or may not
address, or your application doesn't support by design (e.g. perhaps
different users cannot access common data).  Whether your application
protects against them or not, there are many ways of creating
duplicate submissions:

* It might not be a double-click, it could be any subsequent click,
especially if the response is slow enough.
* The user presses refresh on a POST response (although
POST->Redirect->GET mitigates this).
* The user might have cancelled the response (pressing stop/esc), and
re-submitted same/new data.
* The user could be working in multiple browser windows (pressing
CTRL+N in IE8 gives a duplicate window instance, or right-click
duplicate on the tab in Chrome).
* The user could be re-submitting from a cached page (so the old token
is present).
* The user could be working on the same data set using different
devices (even if they have unique tokens, should the second POST
succeed if it overwrites the first?).
* Multiple users may be working on the same data set (same as above).
* An attacker may be replaying captured HTTP requests (would require
non-predictable tokens ideally).

So you still require 'extra-work' server-side to prevent
double-posting of the same (or even modified) form data.

A basic optimistic locking pattern would be to keep a version number
with your data e.g. UPDATE table SET ..., version = version + 1 WHERE
... AND version = postVersion (just an example, e.g. incrementing the
version would be predictable, so not a great way to mitigate against a
replay attack that was aware of this).  There wouldn't be any need to
give tokens a definite expiry or to delete them if they are stored
with the data.


More information about the thelist mailing list