使用 ReactJS 在 localStorage 中存储 JWT 是否安全?

IT技术 reactjs local-storage jwt
2021-04-07 23:46:59

我目前正在使用 ReactJS 构建一个单页应用程序。

我读到不使用的原因之一localStorage是因为 XSS 漏洞。

由于 React 会转义所有用户输入,现在使用它是否安全localStorage

6个回答

在大多数现代单页面应用程序中,我们确实必须将令牌存储在客户端的某个地方(最常见的用例 - 保持用户在页面刷新后登录)。

共有 2 个选项可用:Web 存储(会话存储、本地存储)和客户端 cookie。这两个选项都被广泛使用,但这并不意味着它们非常安全。

Tom Abbott 很好地总结了JWT sessionStorage 和 localStorage 安全性

Web Storage (localStorage/sessionStorage) 可以通过 JavaScript 在同一个域中访问。这意味着在您的站点上运行的任何 JavaScript 都可以访问 Web 存储,因此可能容易受到跨站点脚本 (XSS) 攻击简而言之,XSS 是一种漏洞,攻击者可以在其中注入将在您的页面上运行的 JavaScript。基本的 XSS 攻击尝试通过表单输入注入 JavaScript,攻击者将其<script>alert('You are Hacked');</script>放入表单中,以查看它是否由浏览器运行并可以被其他用户查看。

为了防止 XSS,常见的响应是对所有不可信数据进行转义和编码。React(大部分)为你做这件事!这里有一个很好的讨论,关于 React 负责多少 XSS 漏洞保护

但这并不能涵盖所有可能的漏洞!另一个潜在威胁是使用托管在 CDN 或外部基础设施上的 JavaScript

汤姆又来了:

现代网络应用程序包括用于 A/B 测试、漏斗/市场分析和广告的 3rd 方 JavaScript 库。我们使用像 Bower 这样的包管理器将其他人的代码导入我们的应用程序。

如果只有您使用的脚本之一遭到破坏怎么办?恶意 JavaScript 可以嵌入到页面中,并且 Web 存储会受到损害。这些类型的 XSS 攻击可以在每个人不知情的情况下获取访问您站点的每个人的 Web 存储。这可能就是为什么许多组织建议不要在网络存储中存储任何有value的东西或信任任何信息的原因。这包括会话标识符和令牌。

因此,我的结论是,作为一种存储机制,Web Storage在传输过程中不会强制执行任何安全标准阅读并使用 Web Storage 的任何人都必须尽职尽责,以确保他们始终通过 HTTPS 而不是 HTTP 发送 JWT。

我想你把这些搞混了?现代 Web 框架对 XSS 具有强大的内置防御。但对于 xsrf 来说并没有那么多。xsrf 的最佳防御是完全避免使用 cookie。本地存储被沙盒化到特定域,这意味着攻击者域无法访问它。Web 框架通过自动编码和清理用户输入来防御 xss。参见angular.io/guide/security
2021-05-25 23:46:59
是的。我推荐 cookie,因为它们提供额外的安全性,以及使用现代 Web 框架防御 CSRF 的简单性。Web Storage(localStorage/sessionStorage)易受 XSS 攻击,攻击面较大,攻击成功可影响所有应用程序用户。
2021-06-02 23:46:59
我来得有点晚了,现在只是阅读这些主题,我对一件事感到困惑,很多人都在谈论如果您受到 Xss 的威胁,您将受到仅 http cookie 的保护,但是,如果您有 xss攻击者不需要窃取您任何东西,他可以简单地从页面上发布帖子以使用该 cookie 冒充您(即使他无法窃取它)。我错过了什么吗???
2021-06-11 23:46:59
所以如果我正确理解你,你推荐饼干吗?只想确认一下。谢谢!
2021-06-16 23:46:59
如果“您推荐 cookie [而不是]”,那么,我可以建议您在答案中的某处说出来吗?而不是只在评论中?
2021-06-17 23:46:59

我知道这是一个老问题,但根据@mikejones1477 所说的,现代前端库和框架逃避了文本,为您提供了针对 XSS 的保护。cookie 不是使用凭证的安全方法的原因是当 localStorage 阻止时 cookie 不会阻止 CSRF(还请记住,javascript 也可以访问 cookie,所以这里的 XSS 不是大问题),这个答案恢复了为什么

将身份验证令牌存储在本地存储中并手动将其添加到每个请求以防止 CSRF 的原因是关键字:手动。由于浏览器不会自动发送该身份验证令牌,如果我访问 evil.com 并设法发送 POST http://example.com/delete-my-account,它将无法发送我的身份验证令牌,所以请求被忽略。

当然,httpOnly 是圣杯,但你不能从 reactjs 或任何 js 框架访问,你仍然有 CSRF 漏洞。我的建议是 localstorage 或者如果您想使用 cookie,请确保像 django 那样对您的CSRF 问题实施一些解决方案

关于 CDN,请确保您没有使用一些奇怪的 CDN,例如像 google 或 bootstrap 提供的 CDN,由社区维护并且不包含恶意代码,如果您不确定,您可以自由查看。

不知道为什么你会说你在使用 cookie 时仍然容易受到 CSRF 的攻击。使用带有标志HttpOnly SameSite=strict的 cookiesecure将确保您在 cookie 中设置的信息安全。然后针对 XSS,您只需确保您的 JavaScript 不知道任何与身份验证相关的数据,例如令牌和密码(意思是,不要将它们存储在 Web Storage 中)——如果您导入恶意脚本,该脚本将无法访问到敏感数据。是的,您也无法通过 JS 访问令牌,但这确实不应该成为问题。
2021-06-05 23:46:59
@miphe 这就是我说的。但是 OP 要求一种从 javascript 访问的方法。在这里,我只是解释存储可从 js 访问的令牌的最佳方法是什么。
2021-06-17 23:46:59

基本上可以将 JWT 存储在 localStorage 中。

我认为这是一个好方法。如果我们谈论的是 XSS、使用 CDN 的 XSS,那么这也是获取客户登录/通行证的潜在风险。将数据存储在本地存储至少可以防止 CSRF 攻击。

您需要了解两者并选择您想要的。这两种攻击并不是您需要注意的全部,请记住:您的整个应用程序仅与应用程序中最不安全的点一样安全。

再次存储是可以的,容易受到 XSS、CSRF、...不是

现在,只需将 Cookie SameSite 设置为strict防止 CSRF。
2021-05-25 23:46:59
除非身份验证方法是一次性代码,或无密码或 2FA
2021-05-28 23:46:59
这就是为什么执行以下操作是安全的: - 将 JWT 存储在 cookie 中,以便无法从 XSS 中检索它 - 将 CSRF 令牌存储在 localStorage 中,以便无法从 CSRF 中检索
2021-06-08 23:46:59
您提出了一个好观点:如果您的站点运行恶意脚本,那么无论如何游戏都结束了。他们可以将 keydown 事件绑定到密码类型的输入,并以这种方式窃取用户的身份验证信息(这比窃取 JWT 身份验证令牌要糟糕得多)。将 JWT 存储在 localStorage 中几乎不会增加 XSS 可能造成的巨大损害。
2021-06-08 23:46:59
当去 localStorage 时。我建议添加 Content-Security-Policy 标头作为额外的安全层,以尽量减少包试图窃取您的令牌的风险。
2021-06-15 23:46:59

如果您使用 CDN 是不安全的:

恶意 JavaScript 可以嵌入到页面中,并且 Web 存储会受到损害。这些类型的 XSS 攻击可以在每个人不知情的情况下获取访问您站点的每个人的 Web 存储。这可能就是为什么许多组织建议不要在网络存储中存储任何有value的东西或信任任何信息的原因。这包括会话标识符和令牌。

通过风暴路径

您需要从外部获取的任何脚本都可能遭到破坏,并且可能会从您客户端的存储中获取任何 JWTS 并将个人数据发送回攻击者的服务器。

您包含的任何 npm 包都是在您的网络上运行的 js。
2021-06-11 23:46:59
该文章的作者从未区分通过 CDN 或直接来自中央服务器的站点上的 XSS。您在这里的解释是否也适用于一般情况,而不仅仅适用于 CDN?
2021-06-12 23:46:59
如果我不打算使用 cdn 会安全吗?
2021-06-13 23:46:59

Localstorage 设计为可通过 javascript 访问,因此它不提供任何 XSS 保护。正如其他答案中所提到的,有很多可能的方法可以进行 XSS 攻击,默认情况下,本地存储不受保护。

但是,cookie 具有安全标志,可以防止 XSS 和 CSRF 攻击。HttpOnly 标志阻止客户端 javascript 访问 cookie,Secure 标志只允许浏览器通过 ssl 传输 cookie,SameSite 标志确保 cookie 只发送到源。虽然我刚刚检查过,目前只有 Opera 和 Chrome 支持 SameSite,所以为了防止 CSRF,最好使用其他策略。例如,在另一个 cookie 中发送一个带有一些公共用户数据的加密令牌。

因此 cookie 是用于存储身份验证数据的更安全的选择。

好吧,如果有人可以在您的网站上执行代码,他不能简单地以您用户的名义在您的网站上发帖吗?好吧,他无法获取您的仅 http cookie,但他可以使用这些 cookie 进行调用,所以我仍然看不到这一点
2021-05-28 23:46:59
@AlexLyalka 并不是说​​ HttpOnly 可以防止 CSRF,而不是所有 cookie 标志一起可以防止 XSS 和 CSRF。SameSite 提供了一些保护,防止 cookie 被发送到与来源不同的站点。尽管我刚刚检查过并且对该标志的支持非常低。也可以使用带有一些用户标识的单独加密令牌来避免 CSRF,该令牌在服务器上进行检查。
2021-06-02 23:46:59
将 jwt 存储在 cookie 中有什么意义?如果然后在我的网络应用程序中,我想在另一个服务器服务中请求。该服务无法解密该 cookie 以获取 jwt。
2021-06-04 23:46:59
@BorjaAlverez 有很大的不同。是的,通过 XSS,有人可以代表登录用户发出请求,但破坏令牌更糟。例如:令牌可能提供对客户端应用程序不使用的 API 的访问;令牌可能包含有关用户的其他信息(电子邮件地址、个人资料和授权);该令牌可用于对您的应用程序进行重放攻击;令牌可以作为一个传递id_token_hint给 OIDC 身份验证服务器;令牌向攻击者提供有关用于对其进行签名的密码的信息;等等。
2021-06-07 23:46:59
无法获得:HttpOnly 如何保护您免受 CSRF 的侵害?
2021-06-20 23:46:59