cookies - 是否设置 cookie 'SameSite=none; 安全”并提供 CSRF-TOKEN 足以防止 CSRF 出现在可嵌入的 Web 应用程序中?
问题描述
我的 Web 应用程序(进一步是 myApp)嵌入到单个第三方网页的 iframe 中。MyApp 设置 cookieSet-Cookie: JSESSIONID=38FE580EE7D8CACA581532DD37A19182; Path=/myapi; Secure; HttpOnly
用于维护用户会话。前段时间它停止在 Chrome 中工作,因为https://blog.chromium.org/2020/02/samesite-cookie-changes-in-february.htmlSameSite
更新更改了对没有属性的 cookie 的默认行为from None
to 的处理Lax
。
我将从 myApp 主机发送 cookie,使用
SameSite=None; Secure
.X-CSRF-TOKEN
每个响应中还包含标头。myApp javascript 获取X-CSRF-TOKEN
并将其放在对 myApp 主机的每个 XHR 请求的标头中。这足以防止 CSRF 攻击吗?是否应该
Access-Control-Allow-Origin: third-party-webpage
在响应中添加标题?
解决方案
我做了更多的研究,并认为我会在这里发表我的结论。我误解了 Antiforgery 中间件的工作原理。配置的 cookieAddAntiforgery
并没有真正将令牌传输给客户端。相反,它似乎是用于验证必须在标头中提供的令牌的加密或散列令牌。这允许无状态地完成令牌的验证,因为浏览器将在每个请求中将此 cookie 的值传回。我将此 cookie 称为下面的“验证 cookie”。
中间件不会自动将令牌本身传输给客户端。这必须通过调用并向客户端GetAndStoreTokens
提供RequestToken
值来设置为后续请求的标头来完成。在我们的应用程序中,我们使用单独的 cookie(我在下面将其称为“令牌 cookie”)来做到这一点。
这是演示此技术的 Microsoft 文章。
我已经确定SameSite=None
用于验证 cookie 和令牌 cookie 是安全的。该SameSite
设置对谁可以读取 cookie 值没有任何影响,它只是确定 cookie 是否会随将来的请求一起发送到服务器。验证 cookie 必须与未来的请求一起发送回服务器,以便可以验证标头中提供的令牌。即使对于跨源请求,也可以发送此 cookie,因为这些请求仅验证标头中是否提供了令牌。
使用令牌 cookie 也是可以接受的,SameSite=None
因为我们仅使用此 cookie 向客户端提供值。在验证令牌时,我们从未从服务器上的 cookie 中读取此值,中间件从标头中读取令牌。无论属性如何,令牌 cookie 的值都不能由不同的来源读取,SameSite
因此保持安全。
我还意识到,Antiforgery 中间件早SameSite=Lax
在 2020 年成为 chrome 的 cookie 的默认值之前就采用了这种确切的模式。在此之前,验证 cookie 的默认行为一直是None
. 因此,我认为可以合理地得出结论,这种技术现在与SameSite=None
之前Lax
成为默认技术一样安全。
注意:似乎有些浏览器无法SameSite=None
正确处理, 因此当应用程序托管在 iframe 中时,这些浏览器的防伪过程可能会失败。
推荐阅读
- android - 在 Unit Test Android 中测试多模块 dagger 依赖项
- system - system verilog HDL - 4bit 输入逻辑计算器
- python - 如何将pytorch张量转换为((value0,row0,column0),(value1,row0,column1)......)等视图?
- c# - 自定义 ViewComponent 查看位置
- javascript - 打开新路线并使其滚动位置从顶部开始,而不会忘记上一页的滚动位置,以防我单击返回?
- php - php 和 FFI 返回结构/联合未实现
- azure-devops - 在 Azure DevOps Pipelines 中分配 AWS Cloudformation 输出变量
- postgresql - 什么时候值得进行 postgresql 数据库复制?
- cmake - 更改 sdkconfig 文件的默认位置
- angular - 重构现有的 Angular 应用程序以添加登录