0

I want to use the security token as hidden input field in my comment form for security purpose. I know if there is only one form in my webpage, I can do some thing like that

$token = sha1(uniqid(rand(), TRUE));
$_SESSION['token'] = $token;

I can use this token in my form

<form action="comment.php" method="post">
<input type="hidden" name="token" value="<?php echo $token; ?>" />
<input type="text" name="comment_body" value="" />
</form>

and on the receiving end, I can do that

if ($_POST['token'] == $_SESSION['token']){ 

   /* Valid Token */

}

But I have about 10 forms on a single page So How I can generate multiple tokens and How to handle them on receiving end. And What If a user open multiple pages?

Rashid Farooq
  • 365
  • 5
  • 17

2 Answers2

0

You can use combination of microtime and mt_rand which I basically use when dealing with such scenario

$tokenLen = 64;

$randomData = mt_rand() . mt_rand() . mt_rand() . mt_rand() . microtime(true) . uniqid(mt_rand(), true);

$token =  substr(hash('sha512', $randomData), 0, $tokenLen);
chandresh_cool
  • 11,753
  • 3
  • 30
  • 45
  • I think, You have not read my question completely. I do not want to know about how to build a secure token, I just want to know that How can I handle multiple tokens. – Rashid Farooq Apr 28 '13 at 09:11
  • You can just store them in separate hidden fields for each form and store them with name appended with form name lets say hidden_form1, hiiden_form2. Then you can easily retrieve them based on which form you submit. – chandresh_cool Apr 28 '13 at 09:13
  • but the Problem is How I will handle them on the receiving end. I mean a single token can be stored in a `$_SESSION['token']` but How I will store multiple tokens and How I will compare them? – Rashid Farooq Apr 28 '13 at 09:15
  • you can store the value $_SESSION['token'] as an array keeping the key as a hidden field name or form name like array("hidden1"=>token1, "hidden2"=>token2) and so on etc, just an option – chandresh_cool Apr 28 '13 at 09:17
0

To prevent CSRF, a single session-dependent token does already suffice.

However, if you want to use a different token for each form, you can associate the token to the form characteristics, e.g., the action URL and method, for example:

// issue token
$form = array('method'=>'POST', 'uri'=>'/comment.php');
if (!isset($_SESSION['CSRF_TOKENS']["{$form['method']}:{$form['uri']}"])) {
    $_SESSION['CSRF_TOKENS']["{$form['method']}:{$form['uri']}"] = generate_csrf_token();
}
echo '<form method="'.$form['method'].'" action="'.$form['uri'].'">';
echo '<input type="hidden" name="CSRF_TOKEN" value="'.$_SESSION['CSRF_TOKENS']["{$form['method']}:{$form['uri']}"].'">';


// check token
$form = array('method'=>$_SERVER['REQUEST_METHOD'], 'uri'=>$_SERVER['REQUEST_URI']);
if (isset(${'_'.$form['method']}['CSRF_TOKEN'], $_SESSION['CSRF_TOKENS']["{$form['method']}:{$form['uri']}"]) && ${'_'.$form['method']}['CSRF_TOKEN'] === $_SESSION['CSRF_TOKENS']["{$form['method']}:{$form['uri']}"]) {
    // token valid
} else {
    // token missing or invalid
}

Another possible solution is to used signed CSRF tokens. You can add the given example as much additional information besides the user ID as you want to further limit the validity of the token.

Community
  • 1
  • 1
Gumbo
  • 643,351
  • 109
  • 780
  • 844