为什么Express/Connect会在每个请求中生成新的CSRF令牌?

Ole*_*leg 6 security csrf node.js express

据我所知,有两种方法可以防止CSRF攻击:1)每个会话的令牌,以及2)每个请求的令牌

1)在第一种情况下,当用户的会话初始化时,仅生成一次CSRF令牌.因此,用户只能同时使用一个有效令牌.

2)在第二种情况下,在每个请求上生成新的CSRF令牌,之后旧的CSRF令牌变为无效.利用vunerability更加困难,因为即使攻击者窃取了一个令牌(通过XSS),也会在用户进入下一页时过期.但另一方面,这种方法使得webapp不太可用.这是来自security.stackexchange.com的一个很好的报价:

例如,如果他们点击"后退"按钮并使用新值提交表单,则提交将失败,并且可能会遇到一些恶意错误消息.如果他们尝试在第二个选项卡中打开资源,他们会发现会话在一个或两个选项卡中随机中断

在分析Node.js Express框架(基于Connect)时,我注意到每个请求都会生成一个新的CSRF令牌,但旧的令牌 不会变为无效.

我的问题是:在每个请求上提供新的CSRF令牌而不是使旧的无效的原因是什么?为什么不在每个会话中生成一个令牌?

谢谢你,对不起我的英文!

use*_*109 4

CSRF 令牌是随机数。它们应该只使用一次(或在很长一段时间后安全使用)。它们用于识别和授权请求。让我们考虑一下防止 CSRF 的两种方法:

  1. 每个会话固定一个令牌:这样做的缺点是客户端可以将其令牌传递给其他人。这可能不是由于嗅探、中间人或某些安全漏洞造成的。这是对用户的背叛。多个客户端可以使用同一个令牌。遗憾的是对此我们无能为力。

  2. 动态令牌:每当服务器和客户端之间发生任何交互或发生超时时,令牌都会更新。它可以防止使用较旧的令牌以及多个客户端同时使用。

动态令牌的缺点是它限制返回并从那里继续。在某些情况下,可能需要重新加载,例如如果实施购物车,则必须重新加载以检查是否有库存。CSRF 将防止重新发送已发送的表格或重复购买/出售。

细粒度的控制会更好。对于您提到的场景,您可以不进行 CSRF 验证。然后不要对该特定页面使用 CSRF。换句话说,按路由处理 CSRF(或其例外)。

更新

我只能想到单个动态令牌比多个动态令牌更好的两个原因:

  1. 多个令牌确实更好,但至少有一个像上面这样的动态令牌。这意味着设计一个可能变得复杂的详细工作流程。例如,请参见此处:

    1. https://developers.google.com/accounts/docs/OAuth2
    2. https://dev.twitter.com/docs/auth/implementing-sign-twitter
    3. https://developers.facebook.com/docs/facebook-login/access-tokens/

    这些是访问其 API(表单提交等)而不仅仅是登录的令牌。每个人的实现方式都不同。除非有良好的用例,否则不值得做。您的网页将大量使用它。更何况现在表单提交并不简单。

  2. 动态单一令牌是最简单的,并且在库中很容易获得。所以可以在旅途中使用它。

多种代币的优点:

  1. 可以实现交易。您可以在请求之间进行排序。
  2. 可以从超时和身份验证错误中回退(您必须立即处理它们)。
  3. 安全的!比单个令牌更稳健。可以检测令牌滥用、黑名单用户。

顺便说一句,如果您想使用多个令牌,您现在拥有 OAuth2 库。