【问题标题】:Why should I put a CSRF token in a JWT token?为什么要将 CSRF 令牌放入 JWT 令牌中?
【发布时间】:2016-05-03 00:18:11
【问题描述】:

我想对 Stormpath post 中的 JWT 令牌和 CSRF 提出疑问,解释将 JWT 存储在 localStorage 或 cookie 中的优缺点。

[...] 如果您使用 JS 从 cookie 中读取值,这意味着您 无法在 cookie 上设置 Httponly 标志,所以现在您网站上的任何 JS 可以读取它,从而使其具有与存储完全相同的安全级别 localStorage 中的一些东西。

我试图了解他们为什么建议将 xsrfToken 添加到 智威汤逊。不将您的 JWT 存储在 cookie 中然后将其提取 并将 JWT 放在 HTTP 标头中并验证 基于 HTTP 标头的请求完成与 Angular 的 X-XSRF-TOKEN?没有其他域可以在 如果您基于标头中的 JWT 进行身份验证,则代表用户, 因为其他域无法从 cookie 中提取 JWT。我不 了解 JWT 中 xsrfToken 的用途——也许它只是 额外的防御层——这意味着攻击者必须 您的网站上有一个受损的脚本,并且当时有一个用户 CSRF。所以 他们必须以两种方式击中你才能发动攻击。

帖子链接在this answer,其中说:

最后一件事是确保您在每个节点上都有 CSRF 保护 HTTP请求确保外部域发起请求 您的网站无法运行。

[...] 然后,在每个请求进入您的服务器时,确保您自己的 JavaScript 代码读取 cookie 值并将其设置为自定义 标题,例如X-CSRF-Token 并在每个请求中验证该值 服务器。 外部域客户端无法为 除非外部客户端获得授权,否则向您的域发出请求 通过 HTTP 选项请求,因此任何 CSRF 攻击尝试(例如 一个 IFrame,无论如何)对他们来说会失败。

即使他们可以设置自定义标头,他们也无法访问存储 JWT 令牌的 cookie,因为只有在同一域上运行的 JavaScript 才能读取 cookie。

他们唯一的方法是通过 XSS,但如果存在 XSS 漏洞,JWT 中的 xsrfToken 也会受到损害,因为在受信任的客户端域中运行的恶意脚本可以访问 cookie 中的 JWT 并在请求中包含标头使用 xsrfToken。

所以方程应该是:

  • TLS + 存储在安全 cookie 中的 JWT + 请求标头中的 JWT + 无 XSS 漏洞。

如果客户端和服务器在不同的域中运行,服务器应该发送 JWT,客户端应该使用 JWT 创建 cookie。 我认为这个等式在这种情况下仍然有效。

更新: MvdD agree with me

由于浏览器不会自动将标头添加到您的请求中, 它不易受到 CSRF 攻击

【问题讨论】:

    标签: javascript cookies csrf jwt owasp


    【解决方案1】:

    我是 Stormpath 博客文章的作者。将 XSRF 令牌存储在 JWT 中并不是关于它在 JWT 中,而是关于它在 cookie 中。 cookie 应该是 httpOnly,所以你不能从 Javascript 中读取它。

    现在,我认为引起一点混乱的一点是我在谈论角度。 Angular 也将它设置为只有 XSRF cookie(不是 httpOnly),以便在请求时将其放入标头中(只能由同一域上的 javascript 完成)。这些不是同一个cookie。

    如果您考虑在您的应用程序中实现 XSRF 支持,这已经通过存储服务器端状态和存储 XSRF 的点来完成。将其存储在 httpOnly cookie 中意味着使用 XSRF 实现无状态。在这里,您将验证 JWT 签名,从声明中获取 XSRF,并将其与标头进行比较。

    您的问题的答案是您不需要在服务器上存储状态。

    【讨论】:

    • 感谢您的回答,您写了一篇不错的帖子!我仍然不明白为什么需要 XSRF 令牌。也许如果您分享一个具体案例,将 JWT 存储在非 httpOnly cookie 中并将其在标头中发送回服务器(带有 TLS 且没有 XSS 漏洞),用户可能会在不通知的情况下发出恶意请求。
    • 刚刚发布了一个答案。请让我知道你的想法。
    • 我是 JMU 的毕业生,也是 Tom :)
    • 在 JWT 中显式 XSRF 的缺点是它会增加大小。为什么不直接使用 JWT 的哈希作为 XSRF 令牌?毕竟,如果攻击者可以读取仅限 https 的 cookie,那么您的 XSRF 令牌不会增加太多价值。您可以在没有服务器端状态和额外 cookie 大小的情况下验证该哈希。
    • @Tom 快一,你认为我们应该使用 xsref cookie 并验证我们是否使用 jwt 进行身份验证
    【解决方案2】:

    我的理解是这样的:

    • Store JWT 是一个仅限 HTTP 的 cookie。
    • 在该 JWT 中,存储 XSRF 令牌的散列版本。
    • 在客户登录时向他们发送 XSRF 令牌,以便他们可以将其存储在本地存储中
    • 稍后,当客户端发送请求时,JWT 会自动通过 cookie 随每个请求一起发送,然后您还可以通过标头或查询变量发送 XSRF 令牌,并在服务器端重新散列以与 JWT 中的内容进行比较在服务器上

    您的 JWT 受到保护,不会在 XSS 中被盗,并且您受到 XSRF 的保护。 XSS 仍然可以在您的浏览器上执行,但只能对浏览器中的该会话造成损害。归根结底,您无法阻止某人编写仅在您的浏览器上运行的非常详细的脚本,因此 Web 开发人员仍然需要传统的安全措施来防止 XSS。

    【讨论】:

    • 没错!我在这里用这种方法写了一个针对漏洞表面区域的答案:stackoverflow.com/questions/37770967/…
    • 还有,去吧,公爵们! :)
    • 我仍然对此感到困惑。那么,这是一种安全的技术吗?另外,我不明白为什么我需要csrf。因为如果我存储在本地存储中,那么是可见的。你能指出一个例子的方向吗!
    • 那么为什么不将 jwt 存储在本地存储中并将 XSRF 令牌存储在 HttpOnly Coockie 中呢?这样,jwt 的有效性只有在服务器同时接收时才会给出。
    • @Gacci 你只需要调查 XSRF 攻击和 CSS 攻击是什么 - localStorage 可以防止前者(这是一种看不到 localStorage 的攻击),而 http-only cookie 可以防止后者(这是一种无法利用所述 cookie 的攻击)。
    猜你喜欢
    • 2021-11-04
    • 1970-01-01
    • 2012-08-25
    • 2019-07-12
    • 2012-11-20
    • 2013-12-28
    • 2019-03-25
    • 2020-02-22
    • 2020-12-03
    相关资源
    最近更新 更多