如果我使用 Bearer JWT,是否需要 CSRF 令牌?

信息安全 饼干 csrf 节点.js angularjs
2021-08-17 03:39:09

上下文:Angular 站点托管在 CloudFront 后面的 S3 上,与用作 API 的 Express 服务器分开,几乎所有请求都是 XMLHttpRequests。所有请求都是在没有 cookie 的情况下发送的(默认情况下 withCredentials = false),我使用 JWT Bearer 令牌进行身份验证,方法是从角度的 cookie 中获取它并放置到Authorization标题中(这种技术是CSRF Wiki page中描述的一种技术)。

在 Express 网站上,我不允许CookieAccess-Control-Allow-Headers.

cookie 有secure: true标志,并不是httpOnly因为我需要手动访问它们。

我还在这篇 Medium 文章中读到 JSON-Web-Tokens(JWT)/Bearer Tokens

毫无疑问是预防 CSRF 的最佳方法之一

问题 1:如果我将 X-XSRF-Token 标头添加到每个请求,例如通过检查 JWT 有效负载中的相同值来使机制无状态,我会增加额外的安全性吗?(我在这个线程中读到了它

问题 2:我真的需要额外的安全措施来对抗 CSRF 采取我所描述的一切吗?

4个回答

这是相关的,但不一定能 100% 回答您的问题:

https://security.stackexchange.com/a/166798/149676

简而言之,只要身份验证不是自动的(通常由浏览器提供),那么您就不必担心 CSRF 保护。如果您的应用程序通过Authorization标头附加凭据,则浏览器无法自动验证请求,并且 CSRF 是不可能的。因此,我会稍微改写一下您文章中的引用:并不是承载令牌是抵御 CSRF 攻击的最佳防御措施,而仅仅是 CSRF 是一种攻击向量,专门攻击浏览器自动提供身份验证的请求(通常是 cookie和基本身份验证),因此如果浏览器无法对您进行身份验证,CSRF 无关紧要。

如果不存在承载令牌,您可能应该确保并在服务器端验证您的应用程序不会默默地退回到 cookie 验证。我可能会偶然看到类似的东西进入应用程序,并且由于无论您是否希望它们都会发送 cookie,因此它可能会导致“本应”免疫的页面上出现无意的 CSRF 漏洞CSRF。

因此,我认为您的问题一和问题二都可以以同样的方式回答。如果您只使用 Bearer 令牌而不是 cookie 进行身份验证,则无需担心 CSRF 漏洞,也不需要额外的安全步骤。

通常,CSRF 发生在浏览器自动添加标头(即:Cookie 中的会话 ID),然后使会话经过身份验证时。Bearer 令牌或其他需要手动添加的基于 HTTP 标头的令牌会阻止您使用 CSRF。

当然,但有点跑题了,如果你有 XSS 漏洞,攻击者仍然可以访问这些令牌,但它不会成为 CSRF 错误。

以前的答案是坚如磐石。我会跳到这里来提供更多的背景和一点警告。有很多使用 JWT 的方法;会话管理就是其中之一。尽管它在处理超时和重新认证等高级要求时存在一些缺点。

此外,我还看到 JWT 放在Cookies中。正如其他人所说,CSRF 保护并非来自使用 JWT 本身。它来自使用承载 [JWT]方案将其作为授权标头提交。

问题 1:如果我将 X-XSRF-Token 标头添加到每个请求,例如通过检查 JWT 有效负载中的相同值来使机制无状态,我会增加额外的安全性吗?(我在这个帖子中读到过)

如果您通过 XHR 作为 Authorization 标头提交它,那么没有额外的 X-XSRF-Token 标头不会添加“额外”安全性

问题 2:我是否需要针对 CSRF 采取我所描述的一切采取额外的安全措施?

,您当前的设置没问题。

不久前,我编写了一个Web 身份验证技术指南及其安全属性(它也有JWT 部分)。这是最终的备忘单,以紧凑的形式描述了所有方法。

我觉得强调一些关于单页应用程序(或来自任何前端的请求)可能会使 CSRF 保护无用的内容很重要。起初我认为这可能有点离题,但我正在重新考虑(请参阅底部的注释)。

我的观点:也许你有一些前端应用程序代码在从 URL 加载应用程序时自动向 API 发出请求(最常见的例子之一是验证电子邮件地址)。在这种情况下,你是否有 CSRF 完全无关紧要。只要您的前端应用程序发生某些事情而不需要特定的用户操作,那么 CRSF 保护就无关紧要了,因为攻击者有一种“合法”的方式来执行某些操作,只需让您打开您的前端应用程序。

我想到的一些可以在前端自动执行的动作的例子

  • 身份验证(生成访问令牌等)
  • 验证电子邮件
  • 按照电子邮件链接自动对某些内容进行评分
  • (取消)订阅电子邮件/时事通讯
  • 下载文件(如果前端应用程序在将下载请求转发到服务器之前预处理了一些东西)
  • 加入一个项目,一个小组
  • 验证推荐人代码

其中一些用例(如验证电子邮件)可能不需要身份验证并且相对无害,但其他一些用例(如加入群组)仅在您通过身份验证时才有意义,这意味着您可以通过某种方式自动执行经过身份验证的请求一个 API。如果用户对所发生的事情有一些直接的反馈(假设您的前端确实向您的用户提供了您的反馈),并且如果他们可以撤消这些操作,那么危险可能会降低,但这仍然是一个攻击媒介。

我们经常将“CSRF”视为一种防止直接发送到服务器应用程序或 API 的请求的方法。如果我错了,请纠正我,但该定义似乎涵盖了恶意人员无法看到所发生结果的任何攻击,包括使用前端应用程序代码。