The "Double Submit" Issue from the Server Side

food-deli-015 There are many times when you might want to ensure that a user only submits information to your system once.  The most common, of course, is when you are collecting credit card information for a purchase.  But there are other times as well.

The most common way of dealing with this is by using javascript to disable the submit button.  Since most people using the web have javascript enabled, this works 99% of the time.  But there are people who are so paranoid that they have turned off JavaScript and there are people browsing now with hand held devices that don’t support JavaScript (yet).  This means we must also protect ourselves from the double submit issue on the server side.

I first had this issue a few years ago on an application that people filled out to determine their chances of getting into the top 100 colleges and universities in the country.  We didn’t want to charge people twice for the information.  Since we could be pretty sure that the same person would not be filling out two forms at he same time, we simply set a session variable to "YES" and checked it before billing them.  But an even more foolproof system would be to hash the data they are buying and store that in the session variable.

Here is some sample code:

string yourDataHere =
    "your data needs to be built up as a string";
string hashedData =
    (yourDataHere, "MD5");
if (Session[hashedData] == null)
    Session[hashedData] = "YES";
    // do the rest of your processing here.

And because Sessions are locked, you won’t even have to worry about a race condition.  The second post won’t even be processed until the first request completes.

See: Session State Uses Reader/Writer Lock

Related Post

6 Responses to “The "Double Submit" Issue from the Server Side”

  • [...] The "Double Submit" Issue from the Server Side (Dave M. Bush) [...]

  • Swizec:

    Hashing doesn’t work on the most common double submit problem. That is when the user clicks submit multiple times before the page loads. This would mean that you get several POST requests all with the same data and none with the hash in the session since the forms were sent before session data had time to change.

    A better way would be to check the database for duplicates before adding new content. Or by putting time into a hidden form field, then having it as a key value in the database. If the user submits a form created at the same time more than once only first time counts, next produces a duplicate key error. Very sturdy.

  • Dave:

    I fail to see the problem. The session variable will exist by the time the second post gets in. I’ve used this method successfully for years (and tested it). It is not some theory I just developed.

    IF you have a database, you method would work too. But it is no more reliable than what I proposed. Depending on the circumstance, you’d want to make sure the duplicate you were checking for included the Session ID so that you are only eliminating duplicates from the same user and not duplicates from any user.

    Personally, I like the session method because it quickly identifies the duplicate and means my code doesn’t have to do all of the other processing I would normally have to do prior to putting the information in the database. If I had a database, I’d probably also have duplicate key checks. It all depends on the actual problem behind the solution. This is a generic solution that handles any situation.
    BTW, clicking on your URL caused my browser to crash (on multiple computers) so I removed it.

  • Mike:

    are we talking session variables?

    Wont those get erased on an app pool recycle? Or even get mangled if the web app is running in a web farm?

  • Oh, maybe it’s different in ASP then.

    And my URL shouldn’t be causing anything to crash, must’ve been your flash plugin because the front page currently holds a youtube video.

  • Dave:

    Yes we are talking about ASP.NET session variables.

    Yes, they will get erased on an app pool recycle if you are using inproc sessions, but you should be using a session server of some type even on a single server, which will prevent that problem.

    On a web farm you woud also use a session server and no there will not be any issues because of the web farm. If there are, you haven’t set your farm up correctly.

    See: for a further discussion on inproc vs session servers.