CSRF Double Submit Cookie 基本上是“不安全的”
Posted
技术标签:
【中文标题】CSRF Double Submit Cookie 基本上是“不安全的”【英文标题】:CSRF Double Submit Cookie is basically "not Secure" 【发布时间】:2021-04-27 10:53:22 【问题描述】:来自OWASP page:CSRF 攻击有效,因为浏览器请求自动包含所有 cookie,包括会话 cookie。
为了防止这种情况,我们可以使用双重提交 cookie 哈希。 在我找到的一些示例代码中,基本上都找到了这个算法。
受害者访问应用程序:
-
后端:生成登录cookie和与登录相关的哈希字符串
饼干
前端:将哈希字符串存储到第二个 cookie 中(例如:
CSRF 令牌 cookie)
前端(安全):通过登录发送请求
cookie 和 CSRF HTTP 标头,其中标头值被提取
来自 CSRF 令牌 cookie。
攻击者:
-
使用某种社交媒体工程让用户点击恶意链接,该恶意链接使用会话 cookie。
攻击者然后窃取此会话 cookie 以作为受害者登录
双重提交 cookie 应该可以防止这种攻击,因为攻击者还需要在 HTTP 标头中提供有效的 CSRF 令牌。
我还是不明白:如果浏览器请求自动包含所有 cookie,这意味着在点击恶意链接时,登录 cookie 和 CSRF-token cookie 也将包括在内,攻击者窃取了它们。 所以攻击者只需要从 CSRF-token cookie 中提取值,并使用他窃取的登录 cookie 和提取值的 CSRF HTTP 标头创建自己的 API 访问?
我错过了什么吗?
谢谢
【问题讨论】:
【参考方案1】:这里似乎有些东西混淆了。
因此,在原始同步器令牌模式中,您将生成一个随机令牌,将其存储在服务器端以供用户会话使用,并将其发送到客户端。然后,客户端会将令牌作为表单值或请求标头发送回来,但 不是 作为 cookie,因此它不会自动发送 - 这就是重点。 (并且服务器当然会将请求中的令牌与会话中的令牌进行比较。)
在双重发布中,令牌甚至不需要在服务器端生成,客户端也可以这样做(或者服务器可以发送它,如果我们接受加密在javascript)。
令牌将作为 cookie 以及其他内容(表单值、请求标头、未自动发送的任何内容)发送。如果服务器将其作为 cookie 发送(显然没有 httpOnly),则客户端可以从中读取它,并将其作为非 cookie 也包含在请求中。服务器将再次比较两者。
关键在于,attacker.com 上的攻击者将无法访问应用程序域的 cookie(既不读取也不写入)。因此,如果客户端可以读取 cookie 并将其作为其他内容包含在请求中,则该客户端必须在应用程序源上运行(如果我们仅讨论未修改的浏览器),因此不会执行 CSRF。客户端也可以自己创建整个令牌,因为攻击者.com 仍然无法为应用程序域创建 cookie。
所以基于上述,如果一切都只是在cookies中,那么实现是错误的,并不能防止CSRF。
【讨论】:
【参考方案2】:使用双重提交 cookie 的 CSRF 保护并不安全。 因此,在 OWASP 文档中,双重提交 cookie 被归类为纵深防御之一。
原因是 cookie 可以由第三方通过 MITM 攻击设置。
HTTPS 请求和响应不能被窃听或修改。但是,MITM 攻击可以修改 HTTP 响应(纯文本)。 攻击者可以将受害者定向到http://example.com/(目标站点)以发送明文http请求。 然后,作为响应,攻击者可以使用 MITM 返回一个 Set-Cookie 标头。
HTTP / 1.1 200 OK
Set-Cookie: CSRFTOKEN=XXXXXXXXXXXXXXXXXXXXXXX;
这个 CSRFTOKEN 是在受害者的浏览器中设置的。 接下来,攻击者在下方设置一个 CSRF 陷阱页面。
<form action="https://example.com/target" method="POST">
<input type="hidden" name="mail" value="evil@example.net">
<input type="hidden" name="token" value="XXXXXXXXXXXXXXXXXXXXXXX">
<input type="submit">
</form>
上述表单的目的地是一个https页面,但是http响应设置的cookie在https请求上也是有效的。 所以 cookie 和 hidden 参数将被发送相同的值,绕过 CSRF 保护。
【讨论】:
nodejs 的中间件叫做 csurf。它可以配置为在 cookie 中发送 csrf 机密,同时在标头中发送令牌。有人可能会争辩说,这里的 MITM 攻击可以用 csrf 秘密篡改 cookie。但是,如果我对 cookie 中的部分(服务器端)进行签名,那么中间的任何篡改都会在服务器上检测到,并且 CSRF 验证将失败。这足以说明我们强化了“固有”不安全的“双重提交”模式吗? 是的。签名令牌是安全的,因为外部攻击者无法生成有效令牌。以上是关于CSRF Double Submit Cookie 基本上是“不安全的”的主要内容,如果未能解决你的问题,请参考以下文章
使用 CSRF_COOKIE_HTTPONLY 将 Django CSRF 令牌传递给 Angular