Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent Double Form Submit using Tokens

Tags:

php

I am trying to prevent the user from double submitting the forum by adding token hidden field.

So here is what I have done so far (before the forum loads I have this code to create a token with the current time as a value.

$token = time();
setcookie('formToken', $token, time() + 3600);

in my forum I have a hidden input like this

<form method="post" action="'.$PHP_SELF.'?action=update">
<input type="hidden" name="token" value="'.$token.'" />
<input type="submit" value="go" />
</form>

now on the top of my page where $action == "update" I have this code

if(isset($_POST)  &&  ($_POST['token'] != $_COOKIE['formToken'])){
    $error_list .= '<li>You can not submit this forum twise.</li>';
} 

if i hit F5 to refresh the page it submit the form again without displaying my error.

like image 418
Jaylen Avatar asked Mar 25 '13 23:03

Jaylen


3 Answers

I suggest you to use use the PRG pattern (Post/Redirect/Get), which is also implemented by forums like phpbb.

Post/Redirect/Get (PRG) is a web development design pattern that prevents some duplicate form submissions, creating a more intuitive interface for user agents (users). PRG implements bookmarks and the refresh button in a predictable way that does not create duplicate form submissions.

http://upload.wikimedia.org/wikipedia/commons/3/3c/PostRedirectGet_DoubleSubmitSolution.png

like image 184
gd1 Avatar answered Sep 27 '22 23:09

gd1


gd1 answer will not prevent double click submission or accidental double submit by various jQuery bindings on a complex javascript form code.

Double click may be even faster then disabling submit button, or hiding it with javascript, so this would not be a full answer either.

The session token will not work either because session is not yet written and thus available or updated for the second process which may be just milliseconds away sharing the same session ID. The session is stored only upon completion of the fist process.

Cookie technique could be an answer as far as both processes are able to communicate over cookie in a blocking way, which may result to the same problems as the session sharing above.

The best solution would be to use server's shared memory access to check if the other process had already processed the data (order, payment, etc..) with the pregenerated data hash, or use database table blocking select and insert to check if the pregenerated hash has been already submitted.

like image 40
user2241415 Avatar answered Sep 27 '22 22:09

user2241415


Why not just set a session when the form is successfully submitted?

so $_SESSION['submitted'] = 1;

Then you can check for it.

Or Do

if(isset($_POST['submit'])  &&  ($_POST['token'] != $_COOKIE['formToken'])){
    $error_list .= '<li>You can not submit this forum twice.</li>';
}
like image 37
Harry Beasant Avatar answered Sep 27 '22 22:09

Harry Beasant