GET 请求中的 CSRF 令牌

信息安全 csrf
2021-08-16 18:26:36

根据 OWASP 测试指南,CSRF 令牌不应包含在 GET 请求中,因为令牌本身可能会记录在各种位置,例如日志或由于肩冲浪的风险。

我想知道你是否只允许 CSRF 令牌使用一次,(所以在一个请求之后它就失效了)这仍然是不安全的吗?考虑到当有人记录令牌时,如果攻击者想要执行 CSRF,它将已经失效并且无法使用。

4个回答

如果您以安全的随机方式生成令牌,则攻击者无法从之前的令牌中推断出下一个令牌。所以不应该有任何现实的风险。

这里的另一个重点是使用 SSL。用户和服务器之间的任何代理/反向代理甚至都看不到 GET 参数来记录它们。记录令牌的唯一位置是 SSL 连接的两端。

单击链接后会在用户端登录(例如历史记录)。在服务器端登录是没有风险的(如果你不信任解密 SSL 流量的地方,那么问题就更大了)。

GET 请求应该是幂等的,这意味着您不能使令牌一旦使用就无效,因为任何重复请求都不会给出相同的响应。

GET 请求也不应该对系统进行状态更改,因此不应该要求有 CSRF 保护。即使注销也不应该是实际执行注销的方法的 GET 请求(尽管在 POST 请求执行操作之前,您可以有一个导航到另一个页面的 GET 链接)。

要解决幂等问题,使用重复的 GET 请求并提供相同的 CSRF 令牌,您可以显示来自第一个请求的缓存响应,而无需进行任何状态更改。但是,如果您完全更改状态,您仍然违反标准,请参阅rfc7231


如果请求方法定义的语义本质上是只读的,则请求方法被认为是“安全的”

在本规范定义的请求方法中,GET、HEAD、
OPTIONS 和 TRACE 方法被定义为安全的。

作为旁注,我还认为资源密集型进程也应该是 POST(具有 CSRF 保护)而不是 GET,否则攻击者可以使用 CSRF 向量对系统进行 DoS。

因此,如果您需要 CSRF 作为方法,则不要将其实现为 GET。

考虑到当有人记录令牌时,如果攻击者想要执行 CSRF,它将已经失效并且无法使用。

如果用户获得地址但未能实际使用令牌(由于瞬时网络故障等),则存在极端情况。对于 CSRF 令牌来说,这不太可能足以担心,但对于其他更敏感的令牌来说可能是一个问题。

不过,一次性使用的 CSRF 令牌往往会带来可用性问题,例如破坏导航和多标签浏览……更不用说它们超级丑陋了。:-) 鉴于 GET 请求应该是幂等的,因此不需要 CSRF 保护,token-in-URL 通常是一种设计味道。但我怀疑你可以在这里利用很多东西。

它可能足够安全,但并不能完全消除肩部冲浪和伐木问题。攻击者可以暂时拒绝网络,以便他可以在用户有机会之前使用肩扛令牌,并且请求可能会显示在日志中,但不会在网站(或数据库或网络)关闭时失效尝试的页面加载。除此之外,当您将令牌放入 POST-data 时,我想不出任何不会发生的漏洞。

不过,我不确定在使用后使所有令牌无效是否可行。我经常在一个新的后台选项卡中打开多个页面,例如在旧的 SMF 论坛上,我中键单击私人消息的删除按钮,这样它就不需要重新加载页面就可以删除另一个页面。您可以为页面中出现的所有链接生成唯一令牌,但随后您会遇到一定程度的复杂性,您不妨开始使用 HMAC 而不是简单的令牌。