Cross-origin CSRF 令牌检查失败

Cross-origin CSRF token check fails

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

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

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

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

我使用 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 请求具有以下 headers:

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

找到解决方案。

www.another.com 正在发送 Cookie header 和 SameSite=lax。这意味着除非启动 top-level 导航,否则不会包含这些 cookie。在 iframe AJAX 呼叫的情况下,这不会削减它。

解决此问题的方法是在 framework.yml 中禁用 SameSite

session:
        cookie_samesite: null <--- THIS

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

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

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

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

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