跨域 CSRF 令牌检查失败

Posted

技术标签:

【中文标题】跨域 CSRF 令牌检查失败【英文标题】:Cross-origin CSRF token check fails 【发布时间】:2020-10-12 14:37:50 【问题描述】:

我有网站www.example.com,它从www.another.com 加载iframe。正在加载的页面包含触发对自身 (www.another.com) 的 AJAX 调用的 html 和 JS。这两个网站都使用 HTTPS。

iframe 加载非常好,脚本正在执行,但是,当我单击提交(它是 iframe 的一部分)时,我得到 www.another.com 由于 CSRF 令牌无效而拒绝了我的请求。 iframe 中的表单确实包含一个 token 字段,该字段有一个值(一些哈希)。

当我直接转到www.another.com 时,ajax 调用工作正常。

据我所知,当 ajax 调用到达服务器时,它没有启动会话,因此无法找到要匹配的令牌。

我使用Symfony 4.4NelmioCorsBundle 来确保正确的CORS。配置如下所示:

nelmio_cors:
    defaults:
        allow_credentials: false
        origin_regex: false
        allow_origin: ['https://www.example.com','https://www.another.com']
        allow_methods: ['GET', 'OPTIONS', 'POST']
        allow_headers: ['Origin','Referer']
        expose_headers: []
        max_age: 3600

失败的 ajax 请求有以下标头:

有什么办法可以解决这个问题吗?

【问题讨论】:

【参考方案1】:

找到了解决办法。

www.another.com 发送带有SameSite=laxCookie 标头。这意味着除非启动***导航,否则不会包含这些 cookie。在iframe AJAX 调用的情况下,这不会削减它。

解决方法是在framework.yml 中禁用SameSite

session:
        cookie_samesite: null <--- THIS

我很清楚潜在的安全后果,但是:

AJAX POST 端点受 CSRF 令牌保护, 这两个网站都是 HTTPS

...所以我想我会没事的。我是吗?

如果有比我上面概述的问题更严重的问题,我真的很期待听到 :)

我想指出的另一件事是我的 CORS 配置并不是真的无关紧要。我的所有请求都是“简单”请求,因此不会触发预检请求。

【讨论】:

以上是关于跨域 CSRF 令牌检查失败的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 CSRF 令牌进行跨域 Ajax 调用?

如何实现跨域请求的csrf保护

CSRF 跨域

前后端分离,解决跨域问题及django的csrf跨站请求保护

CSRF(跨域请求伪造)

用于 AJAX CORS 的 Laravel CSRF 令牌