当前位置: 首页 > 知识库问答 >
问题:

具有多个选项卡的CSRF令牌冲突

杜嘉慕
2023-03-14

我在我的应用程序中构建了CSRF保护,只需在每个页面加载上生成一个随机令牌,将其放入会话,然后将令牌绑定到

<body data-csrf-token="csrf_GeJf53caJD6Q5WzwAzfy">

然后在每个表单操作或ajax请求中,我只需从body标签中抓取令牌并将其发送出去。

这很有效,除了一个大问题。用户正在打开应用程序的多个选项卡,我看到了令牌冲突。例如,用户加载第一个页面并生成令牌,然后切换选项卡,加载另一个页面,从而生成新令牌。最后,他们切换回第一页并提交格式化操作。这将导致无效的CSRF令牌错误。

什么是重新构建此功能的最佳方法,以防止与多个选项卡发生冲突,同时尽可能保持其安全性。

简单地在登录时生成一个令牌是正确的解决方案,而不是在每次页面加载时生成一个新令牌吗?


共有3个答案

谷翰飞
2023-03-14

我遇到了这个问题,在页面加载时,我生成了一个CSRF令牌,如下所示:

$_SESSION["token"] = bin2hex(random_bytes(32));

多个标签导致CSRF不匹配,所以我改为这样:

if (!isset($_SESSION['token'])) {
    $_SESSION['token'] = bin2hex(random_bytes(32));
}

服务器端我这样做(淡化版本):

$csrf = preg_replace("/[^a-zA-Z0-9]+/", "", $_POST["token"]);
if ($csrf !== $_SESSION["token"]) {
    // Give an error
    die ("No valid CSRF token provided");
}

这可以防止XSS攻击,但不会阻止有人访问该页面,获取PHP会话ID(来自标题)和CSRF令牌,并使用Postman或WGET等工具来整理hack API帖子,等等。

这可能就是这个问题存在的原因。。。了解CSRF令牌的保护范围。

缪英锐
2023-03-14

登录时可以使用单个令牌。正如@Josh3736指出的,这很好。

如果您真的希望每页有一个令牌,您可以以$_SESSION存储有效令牌数组。然后,您将在使用单个令牌时过期。您也可以选择在某个超时期后将它们过期,但这只在超时时间短于会话超时时时才有意义。但是,再说一遍,你到底在做什么?单个令牌对于CSRF来说是完美的。

邬楚青
2023-03-14

假设应用使用SSL保护,那么在每次页面加载时生成新令牌不会产生任何价值。它不能阻止利用XSS漏洞的攻击者——无论如何,他们都可以访问新生成的令牌。

请记住CSRF令牌的防御措施:恶意第三方页面盲目尝试将数据发布到您的应用,希望用户登录。在这种攻击中,攻击者永远无法访问CSRF令牌,因此频繁更改它没有好处。

不要浪费时间和资源来跟踪每个会话的多个令牌。只需在开始时生成一个,就可以完成了。

 类似资料:
  • 我已通过以下方式在我的nodejs服务器上实施了CSRF攻击预防— 登录时的用户收到CSRF令牌和cookie(基于JWT的令牌存储在cookie中)。CSRF令牌是使用 每当用户发出请求(GET或POST)时,我都会将客户端发送的cookie和csrf令牌(在标题中)与服务器上存储的cookie和csrf令牌进行比较,应用程序工作正常 但是,当登录用户打开新选项卡或新浏览器窗口时,客户端具有co

  • 我对pytest的一个命令行参数没有问题。 运行程序时: 我得到了预期的回应: 当我尝试多个参数时,我会遇到问题 _____________________________________设置测试应答器2时出错/usr/local/penguin/home/px09/p001/test-suite.py,第9行def测试应答器2(cmdopt2):未找到E夹具“cmdopt2” /usr/loca

  • 问题内容: 因此,我四处阅读,对于拥有CSRF令牌感到非常困惑,但是我应该为每个请求还是每小时生成一个新令牌? 但是,我们最好每小时生成一个令牌,然后我需要两个会话:令牌,到期, 我将如何处理该表格?只需将echo $ _SESSION [‘token’]放在隐藏值表单上,然后在提交时进行比较? 问题答案: 如果您按照表单请求进行操作-那么基本上就可以消除CSRF攻击的发生,并且可以解决另一个常见

  • 问题内容: 我正在尝试在我的项目中实现csrf保护,但无法使其与jQuery Ajax一起使用。(不过,它适用于普通的帖子请求) 如果在发送表单之前使用chrome开发工具篡改令牌,则仍会看到“正在处理数据”文本,而不是错误。 app.js send.jade test.js 问题答案: 在有效负载消息中发送CSRF令牌: 为了简化您的工作,我认为您可以创建一个Jquery插件来执行此操作,如下所

  • 本页描述了解释CSRF攻击的用例(16.1): https://docs.spring.io/spring-security/site/docs/current/reference/html/csrf.html 但是,如果用户确实登录了银行的网站,那么邪恶的网站难道不可能发出GET请求以获取新的CSRF令牌,并在根本不需要用户的情况下撰写帖子吗? 答案必须是否定的,否则CSRF令牌将毫无用处,但我

  • 问题内容: 我有使用mod_wsgi在apache服务器上运行的django,以及由apache(而不是django)直接提供服务的angularjs应用。我想对django服务器进行POST调用(运行rest_framework),但csrf令牌存在问题。 是否可以通过某种方式从服务器设置令牌而不将其作为模板的一部分放置(因为这些页面没有经过django)? 我希望能够通过GET请求以cooki