当 SameSite 设置为 Lax 时,我还需要 CSRF 保护吗?

信息安全 Web应用程序 csrf 同站点cookies
2021-08-29 11:14:32

在安全评估期间,我注意到 Firefox 自动将会话 cookie 的 SameSite 值设置为 Lax。根据 Mozilla规范,“现代浏览器”就是这种情况。

设置为 Lax 的 SameSite 属性似乎可以防止 CSRF(每个不使用 GET 的跨域请求)。显然,过时的浏览器仍然容易受到攻击。

如果会话 cookie 在现代浏览器中默认受到保护,您还会为实现 CSRF 保护而困扰开发人员吗?这取决于您的安全/业务理念,以及应用程序的类型,是否值得付出努力。我对你对此事的看法很感兴趣。显然,在最好的情况下,可以在任何地方实施经典的 CSRF 保护,但是将实施工作作为业务案例出售给开发团队变得越来越难。

4个回答

您仍然需要“传统”的 CSRF 保护。也许这会在未来几年发生变化,但在编写 SameSite 属性时,应该将其视为纵深防御,而不是唯一的防线。这有几个原因:

  • 根据caniuse.com的说法,目前只有 85% 或 92%(如果算上部分支持)全球用户的浏览器支持。例如,Windows 8 上的 IE 11(仍然在世界各地的许多办公室中使用)不支持它,Android 上的 UC 浏览器也不支持。
  • 依靠浏览器自动升级到 Lax 更糟糕,因为并非所有支持的浏览器都这样做。不过,我没有任何数字。但至少,您需要明确设置标志。
  • 你真的相信你的应用程序的所有当前和未来的开发人员永远不会在 GET 请求上更改服务器状态吗?我不会这样做——我什至不会相信自己。如果您想依赖 SameSite,请将其设置为 Strict。
  • 如果您不信任您的子域,SameSite 不会帮助您。请参阅jub0bs这篇精彩文章
  • 正如我在这个答案(第二个要点)中所写的那样,在某些情况下,您将始终需要传统的 CSRF 防御。

TL;DR:仅 SameSite 标志不足以保护您的用户免受 CSRF 的影响。

当前的答案表明我们目前不应该。但是在未来什么时候我们可以开始依赖这个呢?

比较 caniuse 和 MDN 支持表中的数据。您可以观察到不存在支持 TLS 1.3 且不支持 SameSite cookie 的浏览器。

浏览器 同站点 TLS 1.3
边缘 16 79
火狐 60 63
铬合金 51 70
苹果浏览器 12 + 莫哈韦 12.1 + 莫哈韦
歌剧 39 57
iOS 12 12.2

从这张表来看,一个非常方便的答案(因为我们无法有效地测试 SameSite cookie)是:

  • 当您在 Web 服务器上禁用 TLS 1.2 及更低版本时。
  • 如果您不允许在同一域(包括所有子域)上使用用户生成的表单

一旦不再可能与 TLS 1.2 连接。访问您网站的所有浏览器都将支持 SameSite cookie 并强制执行设置。

要重新迭代设置:

SameSite=严格

  • 完美保护来自不同域的所有请求。
  • 没有对子域的保护。

pages.github.com仍然可以针对github.com. 如果您打算允许用户托管的内容,则需要继续使用传统的 CSRF 令牌或使用单独的域,例如github.io不受信任的内容。

SameSite=松懈

  • 依赖 HTTP 动词进行保护。CSRF 保护与确保敏感操作永远不会响应 GET 请求一样好。
  • 没有对子域的保护。

pages.github.com仍然可以针对github.com. 如果您打算允许用户托管的内容,则需要继续使用传统的 CSRF 令牌或使用单独的域,例如github.io不受信任的内容。

相同站点=无

你注定要失败。继续使用传统的 CSRF 令牌。

SameSite=Lax 意味着对 GET 请求没有 CSRF 保护。

根据https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite

Cookies 允许与顶级导航一起发送,并将与第三方网站发起的 GET 请求一起发送。这是现代浏览器中的默认值。

在理想情况下,这可能是足够的 CSRF 保护。但现实世界远非理想。带有非安全 GET 请求的 Web API 绝非罕见(根据HTTP 规范,GET 请求会改变服务器状态,尽管它不应该如此)。

此外,并非所有浏览器都正确实现了相同站点标志(尚未):https ://caniuse.com/#feat=same-site-cookie-attribute

有些年长的人永远不会。

实现额外的显式 CSRF 保护(如同步器令牌模式)更安全。

所有主要浏览器都支持相同站点,这是一个边界问题。

  • 作为开发人员,我通常使用具有内置 CSRF 保护的框架(例如 Spring Security)或 Ajax 端点。实施 CSRF 保护并不麻烦,我现在继续使用它,因为我们有相同的站点 cookie。

  • 作为一名渗透测试人员,我认为 POST 请求缺乏 CSRF 保护是低风险或信息性的。如果 GET 请求允许某个操作,我会标记为更高的风险级别,具体取决于哪些操作易受攻击。