查询框架 CSRF 令牌的存储和处理方式



我知道CSRF实际上是如何工作的,它通常将随机文本存储在会话中,并且在隐藏令牌CSRF字段中的HTML表单上具有相同的文本。当用户提交表单时,HTML 表单令牌与会话 CSRF 匹配并分别验证。

问题是,如果我刷新页面,将生成新的CSRF令牌,并且仅在下次刷新之前有效一次。在这种情况下,如果我在新选项卡中多次打开相同的表单并提交后续表单,框架或任何人将如何在会话中存储令牌并对其进行验证。它是存储最新的令牌还是存储以数组形式生成的所有新令牌,并在验证令牌后从会话中删除令牌。

当HTML表单在多个选项卡中打开并一个接一个地提交时,我无法了解如何处理同一用户的多个令牌。

我正在控制器中转储会话,但根据我的假设无法看到那里的所有令牌。

谁能帮我了解它的处理方式。

我使用 https://github.com/Vundo/CSRF
它是如此简单,它可以得到

session_start();
<form method="post" accept-charset="UTF-8">
<input type="submit" value="<?php echo SUBMIT ?>">
<input type="hidden" name="_token" value="<?php echo CSRF::generate() ?>">
</form>

提交后的接收页面:

$session_start();
if(isset($_POST['xxxxxxx'])) {
if(!CSRF::check($_POST['_token'])){
exit('Wrong Token!');
}

在CodeIgniter中,每次打开表单时,或者在您的情况下,一个新选项卡(您的意思是浏览器选项卡吗?),您都会得到一个令牌。此令牌被存储,并使用form_open输出到隐藏的输入。提交时,将进行检查以确保存储的令牌和表单令牌相同。这是一个非常简单的过程,就像halojoy概述的过程一样。

在评论中,您指出尽管在不同的选项卡中打开了多个表单,您仍然可以提交表单而不会出现CSRF错误。这很可能是由于配置设置$config['csrf_regenerate'] = FALSE;

令牌可以在每次提交时重新生成(默认)或保留 在CSRF Cookie的整个生命周期中也是如此。默认 令牌的再生提供了更严格的安全性,但可能会导致 当其他令牌变得无效时的可用性问题(后退/前进) 导航、多个选项卡/窗口、异步操作等)。你可以 通过编辑以下配置参数来更改此行为

因此,基本上,如果您启用了重新生成,则每次打开带有表单的新选项卡时,都会重新生成cookie。因此,最后打开的表单将是最后一个要设置的表单,并且具有唯一有效的 CSRF 令牌。

例:

  • 选项卡 1:表单将令牌设置为 123,并在隐藏字段中将令牌设置为 123。 (打开选项卡 2)
  • 选项卡
  • 2:选项卡 1 中的表单在隐藏字段中仍有 123 的标记,但现在令牌为 456(重新生成),隐藏字段为 456(有效)

提交时选项卡 1 中的表单将失败,而选项卡 2 中的表单将成功。

最新更新