Cookie 是否可以保护令牌免受 XSS 攻击? [关闭]

2024-04-19

我正在为基于浏览器的 Javascript Web 应用程序构建基于 JWT(JSON Web 令牌)的身份验证机制,使用无状态服务器(无用户会话!),并且我想一劳永逸地知道是否使用存储我的 JWT 令牌在cookie将保护我的令牌免受 XSS 攻击,或者如果没有保护,那么与在我的 Javascript 应用程序中使用浏览器本地存储相比,没有真正的优势。

我在SO和许多博客中看到过这个问题的提出和回答,但我从未见过真正令我满意的答案。


这个问题最初是基于征求意见的基础上提出的——按照我原来的措辞,确实如此。因此,现在让我明确表示,我不想要基于开发人员懒惰等模糊概念的意见 - 这就是基本规则旨在消除的内容。我想要的是一个有证据支持的是/否的答案。任何一个:

  • “是的,可以保护 cookie 免受 XSS 和 CSRF 的影响,具体方法如下” or
  • “不,通过保护您的 cookie 免受 CSRF 的侵害,您始终会使其遭受同样类型的 XSS 攻击,而正是这种攻击使得 cookie 成为了一个好主意”

因此,我将重申这个问题,并提出一些简化的基本规则,并提前指出其中的漏洞,以便各位专家能够纠正我的错误。

基本原则

  • 您的应用程序是一个 javascript 浏览器应用程序 - 它可能位于 AngularJS 中,但也可能是自定义构建的。它通过 REST 调用与服务器通信。比方说,jQuery $ajax 调用。

  • 服务器是无状态的:没有会话管理。

  • 该应用程序使用 JWT 作为主要身份验证令牌(OAuth2 术语中的“访问令牌”),并使用秘密签名密钥在服务器上验证它们

  • 忽略 cookie 的其他重要优点:浏览器管理、编码质量较差的可能性较小等。对于这场战斗,我想考虑绝对安全性,并假设我们可以胜任对任一机制进行编码。

  • 忽略cookie的其他缺点,例如非浏览器应用程序等。对于这场战斗,我们只关心基于浏览器的javascript应用程序。

  • 在非 cookie 方式中使用标头还是请求正文来传输令牌并不重要;如果您使用本地存储与会话存储也没关系 - 忽略那里的任何安全差异。是的,我知道技术上 Cookie 使用标头,请忽略它。


简而言之,我们只对比较 browser-handles-tokens 与 your-javascript-handles-tokens 以及比较 XSS 和 CSRF 安全风险感兴趣。


参赛者

在红色的角落里,Auth0 https://auth0.com/blog/2014/01/27/ten-things-you-should-know-about-tokens-and-cookies#xss-xsrf:本地存储击败 Cookie,因为 XSS 比 CSRF 更容易修复

在蓝色的角落里,风暴之路 https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage:Cookie 胜过标头,因为实际上 CSRF 比 XSS 更容易修复。

(下面详细摘录两个论点)

选择的武器

XSS 和 CSRF(我们将互换使用 CSRF 和 XSRF:C 似乎在文档中更流行,X 在代码中更流行)

这是我对攻击类型的超级简化总结:

假设您的无状态、经过 JWT 身份验证的 javascript 浏览器应用程序用于在线银行,而攻击者“Evil Corp”想要提交 AJAX REST 调用,通过冒充您的用户将资金转移到他们的帐户。

XSS(跨站脚本)

(正如 Stormpath 所指出的,有很多攻击向量 - 我会选择一个)

Evil Corp 购买了用于密码输入的漂亮文本字段小部件的 github 帐户权限。他们知道您的银行网站使用它,因此他们会更新它以在您输入密码并按 Enter 键时提交 AJAX 请求,将资金转入他们的帐户。您的构建系统愚蠢地提取更新并投入生产。

CSRF(跨站请求伪造)

Evil Corp 知道您的银行网站使用 cookie 中的 JWT 来验证交易,因此他们编写了一个 Web 应用程序来提交 AJAX 请求以将资金转移到他们的帐户。他们将其托管在自己的 evil.com 网站上,并在您碰巧在另一个选项卡中登录到银行网站时通过电子邮件(网络钓鱼)或其他方式引诱您前往那里。浏览器提交来自villain.com的请求,但会附加您的JWT,因为它会发送到正确的站点:银行。

标准防御

防御 XSS 的方法是要非常小心站点中的代码,这样您就不会让浏览器处理用户输入的内容而不对其进行清理(删除 javascript 和 html)以及所有 3rd 方库(Evil 的文本字段小部件)使用前均经过审查。正如 Stormpath 正确指出的那样,这很难,几乎是不可能的。

针对 CSRF 的防御是使用双重提交 cookie 的形式。这意味着我们的服务器创建一个令牌(安全随机字符串)并将其以可读 cookie 的形式发送到我们的 Javascript 浏览器应用程序(按照惯例将其称为“XSRF-TOKEN”),并且我们的 Javascript 在每个请求的标头或正文中将其发送回。

实际上,双重提交 cookie 只是防御 CSRF 的一种方法,但其他一些方法需要有状态服务器会话,而没有其他方法(我think!)提供更好的保护。无状态性还可以通过将令牌放入 JWT 中并在服务器端将其与标头或正文中的令牌进行比较来实现。

但这种防御的真正 CSRF 破坏质量是,同源策略意味着只有我们的应用程序加载的 javascript我们的域名可以读取该cookie。因此,即使 evilcorp.com 上的 javascript 可以通过其请求发送我们的 cookie,它也不能embed我们的 XSRF-TOKEN 因为它不能read it首先。

To really简化CSRF:

  • CSRF attacks工作是因为附加 cookie 的浏览器仅依赖于目的地的请求。
  • CSRF defences之所以有效,是因为 Javascript 对 cookie 的访问取决于originJavaScript 的。

Auth0的论点

处理 XSS 比 XSRF 更容易 Cookies 有这个特性 允许从服务器端设置 HttpOnly 标志,以便它们只能 在服务器上访问,而不是通过 JavaScript 访问。这很有用,因为 它保护 cookie 的内容被注入访问 客户端代码 (XSS)。由于令牌存储在本地/会话中 存储或客户端 cookie,它们容易受到 XSS 攻击 让攻击者访问令牌。这是一个合理的担忧,并且 因此,您应该保持令牌过期时间较短。

但如果你 考虑一下 cookie 的攻击面,主要的攻击面之一是 XSRF。现实情况是,XSRF 是最容易被误解的一种 攻击,而普通开发人员甚至可能不理解 风险,因此很多应用缺乏抗XSRF机制。然而, 大家都知道注射是什么。简单来说,如果你允许 在您的网站上输入,然后在不转义的情况下渲染它,您 对 XSS 开放。所以根据我们的经验,保护起来更容易 防御 XSS 胜过防御 XSRF。除此之外,反 XSRF 是 并非每个 Web 框架都内置。另一方面,XSS 很容易 通过使用大多数情况下默认可用的转义语法来防止 模板引擎。https://auth0.com/blog/2014/01/27/ten-things-you-should-know-about-tokens-and-cookies#xss-xsrf https://auth0.com/blog/2014/01/27/ten-things-you-should-know-about-tokens-and-cookies#xss-xsrf

风暴路径的论证

Stormpath 建议您将 JWT 存储在网络 cookie 中 应用程序,因为它们提供了额外的安全性,并且 使用现代 Web 框架轻松防御 CSRF。 HTML5 Web Storage易受XSS攻击,攻击面更大 区域,并且成功攻击后可以影响所有应用程序用户。https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage/ https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage/

Also:

我看到很多关于 cookie 与访问冲突的讨论 代币。虽然我们都被存储会话 ID 的系统所困扰 在 cookie 中,并且该 cookie 不安全,因此会被盗。那 很糟糕,但这不是使用代币的理由。这是避免的一个理由 非安全、非 https cookie。https://stormpath.com/blog/token-auth-spa/ https://stormpath.com/blog/token-auth-spa/

My take

Stormpath 支持 cookie 的论点非常有说服力,但其中有一个漏洞我没有看到他们明确解决:


双重提交 CSRF 防御依赖于这样一个事实:我的 CSRF 攻击者无法访问我的 cookie:其中包含 XSRF-TOKEN 的 cookie。但是,该 cookie 不是和本地存储一样容易受到 XSS 攻击吗?


XSS 漏洞可以运行 javascriptmy域,因此它可以读取与我的 JavaScript 相同的 cookie。 (浏览器不知道这不是我的Javascript)

从另一个角度来看:本地存储与可读 cookie 一样受到同源策略的保护。如果我使用 Auth0 方法,并且 XSS 攻击者知道如何在本地存储中找到我的 JWT 并使用它。同一个攻击者不能使用相同的 XSS 脚本来获取我的 XSRF-TOKEN cookie 并使用它吗?

这两种攻击都要求他们阅读并理解我的 JavaScript 应用程序,但这些内容就在他们的浏览器中。

那么有什么区别呢?一个真的比另一个更安全吗?为什么?



放弃所有希望,除非你能防范 XSS!

Or

根据其他标准选择适合您的方法,因为两者同样安全,同样不安全。


如果你使用cookie,你绝对应该使用双重提交cookie防御,或类似的东西,因为它确实保护你在没有 XSS 的情况下针对 CSRF。也就是说,如果您不这样做,您肯定会受到来自其他域的 CSRF 攻击,甚至不需要 XSS 漏洞即可发挥作用。

但无论哪种方式,您的源代码都是公开可用的(浏览器中的 JavaScript),因此对于有动机的黑客来说,查找从本地存储中提取哪个令牌与读取您的 XSRF-TOKEN cookie 之间的工作量没有显着差异。如果 Evil Corp 可以在您的域中运行一些 JavaScript(即 XSS),那么您就完蛋了。

您在选择时可能需要考虑的非安全相关标准:

  • Cookie 很方便,因为您无需编写 JavaScript 代码来管理令牌 - 只需使用 XSRF。

  • 如果您想使用重定向,它也会变得更加自动。

  • 本地存储更容易适应非浏览器应用程序 - 从服务器的角度来看,也就是说,因为如果你用 Java 编写一个不想处理 cookie 的 Android 应用程序,你的服务器不需要做任何区分在 in 和浏览器之间,因为它不使用 cookie。

不管怎样,你自己决定吧,但要小心你写的 JavaScriptand您使用的第 3 方 JavaScript!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Cookie 是否可以保护令牌免受 XSS 攻击? [关闭] 的相关文章