Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/270.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/security/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何在会话和html表单中处理多个安全令牌_Php_Security - Fatal编程技术网

Php 如何在会话和html表单中处理多个安全令牌

Php 如何在会话和html表单中处理多个安全令牌,php,security,Php,Security,为了安全起见,我想在我的评论表单中将安全令牌用作隐藏的输入字段。我知道如果我的网页上只有一个表单,我可以做类似的事情 $token = sha1(uniqid(rand(), TRUE)); $_SESSION['token'] = $token; 我可以在我的表格中使用这个代币 <form action="comment.php" method="post"> <input type="hidden" name="token" value="<?php echo $t

为了安全起见,我想在我的评论表单中将安全令牌用作隐藏的输入字段。我知道如果我的网页上只有一个表单,我可以做类似的事情

$token = sha1(uniqid(rand(), TRUE));
$_SESSION['token'] = $token;
我可以在我的表格中使用这个代币

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

但我在一个页面上有大约10个表单,所以我可以如何生成多个令牌,以及如何在接收端处理它们。如果一个用户打开多个页面呢?

你可以使用microtime和mt_-rand的组合,我在处理这种情况时基本上都会使用这种组合

$tokenLen = 64;

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

$token =  substr(hash('sha512', $randomData), 0, $tokenLen);
为防止CSRF

但是,如果要为每个表单使用不同的令牌,可以将令牌与表单特征关联,例如,操作URL和方法,例如:

// 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
}
//发出令牌
$form=array('method'=>'POST','uri'=>'/comment.php');
if(!isset($_SESSION['CSRF_TOKENS'][“{$form['method']}:{$form['uri']}])){
$_会话['CSRF_令牌'][“{$form['method']}:{$form['uri']}”]=generate_CSRF_令牌();
}
回声';
回声';
//支票代币
$form=array('method'=>$\u SERVER['REQUEST\u method'],'uri'=>$\u SERVER['REQUEST\u uri']);
如果(isset(${'.'.$form['uri']}['CSRF'u TOKEN'],$'u SESSION['CSRF'u TOKENS'][“{$form['method']}:{$form['uri']}])和&${'.''.$form['method']}['CSRF u TOKEN']====$'CSRF u SESSION['CSRF u-TOKENS'][{'''.$form method['uri']}}}]{
//令牌有效
}否则{
//令牌丢失或无效
}

另一种可能的解决办法是使用。除了用户ID之外,您还可以添加给定的示例,以进一步限制令牌的有效性。

我想,您还没有完全阅读我的问题。我不想知道如何构建一个安全的令牌,我只想知道如何处理多个令牌。您可以将它们存储在每个表单的单独隐藏字段中,并使用附加表单名称的名称来存储它们,比如hidden_form1,hiiden_form2。然后,您可以根据提交的表单轻松检索它们。但问题是我将如何在接收端处理它们。我的意思是单个令牌可以存储在
$\u会话['token']
中,但我将如何存储多个令牌以及如何比较它们?您可以将值$\u会话['token']存储为一个数组,将密钥作为隐藏字段名或表单名,如数组(“hidden1”=>token1,“hidden2”=>token2)等,只是一个选择这个令牌的目的是什么?@Gumbo阻止CSRF攻击。
// 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
}