CSRF Token 长度

信息安全 应用安全 验证 密码分析 身份
2021-09-06 08:53:44

生成随机令牌时是否应该使用任何标准长度的令牌?我们是否应该使用与生成会话 ID 相同的标准?

3个回答

我认为令牌中的 128 位熵是事实上的标准。OWASPCWE都建议至少这样做。Base64 的 20 个字符(能够 120 位)对于 URL 中的某些内容也很方便。我还要指出,在许多情况下,这些代币的播种不当会产生问题。对于一点参考,请参阅http://samy.pl/bh10/中的(一种无味的装饰,但信息量很大)幻灯片。

确保你选择好你的熵源。

这是一个老问题,但我有机会研究这个问题,并决定至少研究一下一些和 CSRF 库默认使用的内容,我的结果如下:

Django : 32 random characters from the set [a-zA-Z0-9] : 190.53 bits of entropy Ruby on Rails : 32 bytes of entropy (encoded as base64) : 256 bits of entropy Spring Security : UUID4 (actually, this seems to use a PRNG, not an RNG, if I'm not mistaken) : 122 bits of entropy OSASP PHP CSRF Guard (https://www.owasp.org/index.php/PHP_CSRF_Guard) : 128 characters from the set [a-z0-9] : 661.75 bits of entropy OWASP J2EE CSRF Guard : 32 characters in the set [A-Z0-9] : 165.44 bits of entropy Oracle ATG version 10.1.1 : a standard Java "long" encoded using ascii base 10: 64 bits of entropy

请注意,我的示例严重偏向于我可以访问其源代码和我熟悉的框架的框架。

我专门尝试找到使用 64 位或更少熵的框架来尝试证明为什么 ATG 会使用标准的 Java“长”并且没有成功,所以我的结论是 64 位可能太短了。

也就是说,假设攻击者每秒可以执行 100,000 次请求,那么平均需要大约 293 万年才能暴力破解 64 位 CSRF 令牌。(与会话 ID 不同,整个令牌空间中不应有多个令牌。)因此,也许 64 位就足够了。

2 ^ 63 / (100,000 * 60 * 60 * 24 * 365) = 2.93 * 10 ^ 6

在 CSRF 中,攻击者可以做出很多猜测。如果员工访问攻击者网站然后去圣诞假期怎么办?攻击者可以发出数百万个跨站点请求。我们对会话 ID 也有类似的担忧。如果获得任一值,则会话受到损害。CSRF 令牌和会话 ID 应该应用相同的强度标准。

在这两种情况下,请确保值 expires攻击者能否在一周内发出 2^128 次请求,但最终他能够做到。如果你的随机数生成器很弱,​​那么你可能会认为你有一个 2^128th 加密随机数,但它可能要少得多。