110 local-storage jwt reactjs
我目前正在使用reactjs构建单页面应用程序.我读到很多不使用localStorage的原因是因为XSS漏洞.由于React逃脱了所有用户输入,现在使用localStorage是否安全?
Kal*_*sev 116
在大多数现代单页面应用程序中,我们确实必须将令牌存储在客户端的某个位置(最常见的用例 - 在页面刷新后让用户保持登录状态).
共有2个选项:Web存储(会话存储,本地存储)和客户端cookie.这两种选择都被广泛使用,但这并不意味着它们非常安全.
Tom Abbott很好地总结了JWT sessionStorage和localStorage安全性:
Web存储(localStorage/sessionStorage)可通过同一域上的JavaScript访问.这意味着您站点上运行的任何JavaScript都可以访问Web存储,因此可能容易受到跨站点脚本(XSS)攻击.简而言之,XSS是一种漏洞,攻击者可以在其中注入将在您的页面上运行的JavaScript.基本的XSS攻击试图通过表单输入注入JavaScript,攻击者将
<script>alert('You are Hacked');</script>表单放入表单中以查看它是否由浏览器运行并且可以被其他用户查看.
为了防止XSS,常见的响应是转义并编码所有不受信任的数据.React(大多数)为你做这件事!这里讨论了React负责的XSS漏洞保护程度.
但这并未涵盖所有可能的漏洞!另一个潜在的威胁是使用托管在CDN或外部基础设施上的JavaScript.
这是汤姆再次:
现代网络应用程序包括用于A/B测试的第三方JavaScript库,漏斗/市场分析和广告.我们使用像Bower这样的包管理器将其他人的代码导入我们的应用程序.
如果您使用的其中一个脚本遭到入侵,该怎么办?恶意JavaScript可以嵌入到页面中,并且Web存储会受到损害.这些类型的XSS攻击可以让每个人在不知情的情况下访问您的网站.这可能是为什么一群组织建议不要存储任何有价值的东西或信任网络存储中的任何信息.这包括会话标识符和令牌.
因此,我的结论是,作为一种存储机制,Web存储在传输过程中不会强制执行任何安全标准.无论谁阅读Web存储并使用它,都必须尽职尽责,以确保他们始终通过HTTPS发送JWT,而不是HTTP.
Mau*_*zar 27
我知道这是一个古老的问题,但根据@ mikejones1477的说法,现代前端库和框架逃脱了文本,为您提供了对XSS的保护.Cookie不是使用凭据的安全方法的原因是,当localStorage执行时,cookie不会阻止CSRF(还记得javascript也可以访问cookie,因此XSS不是这里的大问题),这个答案恢复原因.
将身份验证令牌存储在本地存储中并手动将其添加到每个请求的原因可以防止CSRF关键字:手动.由于浏览器没有自动发送该身份验证令牌,如果我访问evil.com并且它设法发送一个POST http://example.com/delete-my-account,它将无法发送我的authn令牌,所以请求被忽略.
当然,httpOnly是圣杯,但你不能从reactjs或任何js框架访问你仍然有CSRF漏洞.我的建议是localstorage,或者如果你想使用cookies,请确保为你的CSRF问题实现一些解决方案,比如django.
关于CDN,确保你没有使用一些奇怪的CDN,例如谷歌或bootstrap提供的CDN,由社区维护,不包含恶意代码,如果你不确定,你可以自由审查.
Ash*_*Ash 19
我\xe2\x80\x99m 对所有建议不要存储在本地存储中的答案感到不安,因为这很容易受到 XSS 攻击或恶意库的影响。其中一些甚至会进行冗长的讨论,尽管答案相当小/直接,我很快就会到达。
\n建议这相当于说\xe2\x80\x9cDon\xe2\x80\x99不要使用煎锅来烹饪食物,因为如果你有一天晚上喝醉了并决定煎炸,你\xe2\x80\x99最终会被烧焦你自己和你的房子\xe2\x80\x9d。\n如果 jwt 由于 XSS 攻击或恶意库而泄露,那么网站所有者就会遇到更大的问题:他们的网站容易受到 XSS 攻击或正在使用恶意库。
\n答案:如果您确信您的网站不存在这些漏洞,那就去做吧。
\n参考:https://auth0.com/docs/security/data-security/token-storage#browser-local-storage-scenarios
\nVen*_*ryx 15
需要记住的一件事是 JWT 是否:
如果 JWT 是第一方:
那么,无论您将 JWT 存储在本地存储还是安全的 cookie(即 、和)中都没有那么重要[假设您的站点已经使用 HTTPS,它应该使用 HTTPS]。HttpOnlySameSite=strictsecure
这是因为,假设 XSS 攻击成功(即攻击者能够通过现在在所有访问者浏览器上运行的 JS 依赖项插入 Javascript 代码),无论如何,它都会“游戏结束”;所有本应通过“JWT 令牌验证”保护的命令现在都可以由攻击者执行,只需让他们插入前端 JS 的脚本调用所有需要的端点即可。即使他们无法读取 JWT 令牌本身(因为 cookie 的 http-only 标志),但这并不重要,因为他们可以发送所有需要的命令,并且浏览器会很乐意将 JWT 令牌与这些命令一起发送。
现在,虽然 XSS 攻击情况可以说是“游戏结束”(无论是本地存储还是安全 cookie),但 cookie 仍然好一点,因为攻击者只有在用户拥有该网站时才能执行攻击在他们的浏览器中打开。
这会给攻击者带来以下“烦恼”:
如果 JWT 是第三方:
在这种情况下,这实际上取决于第三方 JWT 允许持有者做什么。
如果他们所做的只是让某人“访问每个用户的基本个人资料信息”,那么如果攻击者可以访问它,那也没什么坏处;某些电子邮件可能会泄露,但攻击者可能可以通过导航到用户的“帐户页面”(其中数据显示在 UI 中)来获取该信息。(拥有 JWT 令牌只是让他们避免上一节中列出的“烦恼”)
相反,如果第三方 JWT 让您做更多实质性的事情——例如完全访问其云存储数据、在第三方平台上发送消息、在第三方平台上读取私人消息等,那么访问 JWT 确实比能够“发送经过身份验证的命令”要糟糕得多。
这是因为,当攻击者无法访问实际的 JWT 时,他们必须通过您的第一方服务器路由所有命令。这样做有以下优点:
有限的命令:由于所有命令都通过您的服务器,因此攻击者只能执行您的服务器旨在处理的命令子集。例如,如果您的服务器仅从用户云存储中的特定文件夹中读取/写入,则攻击者具有相同的限制。
更容易检测:由于所有命令都通过您的服务器,因此您可能能够注意到(通过日志、命令突然增加等)有人发起了 XSS 攻击。这可以让您更快地修补它。(如果他们自己拥有 JWT,他们可以悄悄地调用第 3 方平台,而无需联系您的服务器)
识别攻击者的更多方法:因为命令通过您的服务器,所以您可以准确地知道命令何时发出,以及使用什么 IP 地址发出命令。在某些情况下,这可以帮助您识别谁在进行攻击。IP 地址是最明显的方式,尽管无可否认,大多数能够进行 XSS 攻击的攻击者都知道如何使用代理。
更先进的识别方法可能是弹出一条特殊消息,该消息对于每个用户来说都是唯一的(或者至少分成多个桶),其性质使得攻击者(当他从他的网站加载网站时)自己的帐户)将看到该消息,并尝试基于它运行新命令。例如,您可以链接到“假开发者博客文章”,谈论您正在引入的某些“新 API”,该 API 允许用户访问更多的私人数据;偷偷摸摸的部分是,每个查看博客文章的用户的“新 API”的 URL 都是不同的,这样当尝试使用该 API(针对受害者)时,您就可以确切地知道是谁干的。当然,这依赖于攻击者在受害者旁边的网站上拥有“真实帐户”的想法,并且可能会受到这种方法的诱惑/愚弄(例如,如果攻击者知道您是到他身上),但这是当您可以拦截所有经过身份验证的命令时可以执行的操作的示例。
更灵活的控制:假设您刚刚发现有人在您的网站上部署了 XSS 攻击。
如果攻击者本身拥有第 3 方 JWT,则您的选择将受到限制:您必须全局禁用/重置所有第 3 方平台的 OAuth/JWT 配置。当您尝试找出 XSS 攻击的来源时,这会造成严重的破坏,因为没有人能够从这些第三方平台访问任何内容。(包括您自己的服务器,因为它可能存储的 JWT 令牌现在无效)
如果 JWT 令牌在仅限 http 的 cookie 中受到保护,您就有更多选择:您可以简单地修改服务器以“过滤掉”任何有潜在危险的读/写。在某些情况下,添加此“过滤”是一个快速而简单的过程,允许您的网站继续处于“只读”/“有限”模式,而不会中断一切;在其他情况下,事情可能足够复杂,以至于不值得信任过滤器代码的安全性。但重点是你有更多的选择。
例如,也许您不确定是否有人部署了 XSS 攻击,但您对此表示怀疑。在这种情况下,您可能不想仅仅因为怀疑 XSS 攻击而使每个用户(包括您的服务器在后台使用的用户)的 JWT 令牌失效(这取决于您的怀疑级别)。相反,您可以在更仔细地研究问题时“将内容设置为只读一段时间”。如果结果证明没有任何问题,您只需翻转开关并重新启用写入,而无需每个人都重新登录等。
不管怎样,由于这四个好处,我决定始终将第三方 JWT 存储在“安全 cookie”中,而不是本地存储中。虽然目前第三方 JWT 的范围非常有限(因此,如果它们被盗也没什么大不了的),但这样做是很好的面向未来的,以防万一我希望我的应用程序请求访问更多特权功能将来(例如访问用户的云存储)。
注意:如果JWT 被多个后端服务用作身份验证,并且这些其他服务器的域/IP 地址,上述四个好处(用于在安全 cookie 中存储第三方 JWT)也可能部分适用于第一方 JWT /服务是公共知识。在这种情况下,它们“相当于第三方平台”,从某种意义上说,“仅http cookie”限制XSS攻击者向其他服务器发送直接命令,从而带来上述四点的部分好处。(这并不完全相同,因为您至少可以控制其他服务器,因此您可以为它们激活只读模式等 - 但通常仍然比仅在一个地方进行这些更改需要更多工作)
Had*_*Ali 10
也许人们不应该太担心
Philippe De Ryck 博士撰写了一篇有用的文章,深入了解了漏洞(尤其是 XSS)的真正影响。
这篇文章让人大开眼界!
简而言之,开发人员主要关心的问题应该是保护 Web 应用程序免受 XSS 侵害,而不应该过多担心使用什么类型的存储区域。
Phillipe 博士建议采取以下 3 个步骤:
不要太担心客户端使用哪种类型的存储区域。在浏览器本地存储区域中保存访问令牌将为开发人员节省大量的开发时间!
检查您的应用程序是否存在 XSS 漏洞的可能性。执行彻底的代码审查并了解如何在模板框架范围内避免 XSS。
构建XSS纵深防御机制。了解如何进一步锁定您的应用程序。例如,利用内容安全策略(CSP) 和 HTML5 沙箱。
请记住,一旦您容易受到 XSS 攻击,那么游戏就结束了!
Localstorage 设计为可通过 javascript 访问,因此它不提供任何 XSS 保护。正如其他答案中所提到的,有很多可能的方法可以进行 XSS 攻击,默认情况下,本地存储不受保护。
但是,cookie 具有安全标志,可以防止 XSS 和 CSRF 攻击。HttpOnly 标志阻止客户端 javascript 访问 cookie,Secure 标志只允许浏览器通过 ssl 传输 cookie,SameSite 标志确保 cookie 只发送到源。虽然我刚刚检查过,目前只有 Opera 和 Chrome 支持 SameSite,所以为了防止 CSRF,最好使用其他策略。例如,在另一个 cookie 中发送带有一些公共用户数据的加密令牌。
因此 cookie 是存储身份验证数据的更安全的选择。
小智 6
看待这一点的一种方法是考虑风险或伤害的程度。
您是否正在构建一个没有用户的应用程序,POC/MVP?您是一家需要快速进入市场并测试您的应用程序的初创公司吗?如果是,我可能只会实施最简单的解决方案,并继续专注于寻找适合市场的产品。使用 localStorage 因为它通常更容易实现。
您是在构建具有许多日常活跃用户的应用程序的 v2,还是人们/企业高度依赖的应用程序。被黑客攻击是否意味着恢复空间很小或没有恢复空间?如果是这样,我会仔细查看您的依赖项,并考虑将令牌信息存储在 http-only cookie 中。
使用 localStorage 和 cookie/session 存储各有优缺点。
如第一个答案所述:如果您的应用程序存在 XSS 漏洞,则两者都不会保护您的用户。由于大多数现代应用程序都有十几个或更多不同的依赖项,因此越来越难以保证您的应用程序的某个依赖项不存在 XSS 漏洞。
如果您的应用程序确实存在 XSS 漏洞并且黑客已经能够利用它,那么黑客将能够代表您的用户执行操作。黑客可以通过从 localStorage 检索令牌来执行 GET/POST 请求,或者如果令牌存储在 http-only cookie 中,则可以执行 POST 请求。
将您的令牌存储在本地存储中的唯一缺点是黑客将能够读取您的令牌。
基本上可以将JWT存储在localStorage中。
我认为这是个好方法。如果我们谈论的是XSS,使用CDN的XSS,那么也存在潜在的风险,也可能会导致客户登录/通过。将数据存储在本地存储中至少可以防止CSRF攻击。
您需要同时了解两者并选择所需的内容。两种攻击都不是您需要了解的全部,只是记住:您的整个应用程序的安全性仅与您应用程序的最低安全点相同。
再一次存储就可以了,容易受到XSS,CSRF等的威胁。
我来晚了,但我有更成熟、更现代的身份验证协议(如 OpenID Connect)的优势。
TL;DR:首选方法是将 JWT 令牌存储在内存中:而不是存储在 cookie 中,也不存储在本地存储中。
您希望将验证用户身份的责任与应用程序执行的其他工作分离。Auth 很难得到正确的结果,少数几个花费所有时间思考这些东西的团队可能会担心你我永远无法得到正确的细节。
为您的应用程序建立专用的身份提供商,并使用 OpenID Connect 协议对其进行身份验证。这可能是 Google、Microsoft 或 Okta 等提供商,也可能是与一项或多项其他服务联合的轻量级身份服务器。
将授权代码流与 PKCE 结合使用,让用户进行身份验证并获取应用程序的访问令牌。使用受人尊敬的客户端库来处理 OpenID Connect 详细信息,因此您可以让该库在您的应用程序具有有效令牌时、通过刷新获取新的有效令牌时或令牌无法刷新时通知您的应用程序(因此用户需要再次进行身份验证)。应配置库(可能是默认情况下)以避免存储令牌。
当应用程序首次加载时,它应该始终将用户重定向到您的身份提供商。根据身份提供商处理事务的方式,用户很有可能不必登录。例如,如果您与 Google 或 Microsoft 等身份提供商联合,用户可能会选择一个选项,表明他们他们使用的是受信任的设备,并且希望被记住。如果是这样,他们在很长一段时间内都不需要再次登录,甚至在您的身份验证令牌过期很久之后。这对您的用户来说更加方便。
话又说回来,如果用户表明他们在共享设备上并且将来不应自动登录,您希望强制再次登录:您无法区分刷新浏览器窗口的人和重新打开关闭的浏览器的人并导航到存储在浏览器历史记录中的页面。
应该可以将您的 OpenID Connect (OIDC) 客户端配置为在可能的情况下使用 iframe 以静默方式登录(例如,如果用户已告诉身份提供商信任他们所在的设备),并使用弹出窗口进行登录当需要交互时进行交互式登录。如果由于设备暂时处于睡眠状态而无法自动刷新身份验证令牌,这可以帮助您避免丢失未保存的更改。
当用户第一次导航到您的页面时,唯一可用的上下文应该是他们导航到的 URL 路径/路由,并且在将其发送到身份提供商之前将其存储在本地存储等位置相对简单,因此可以在以下情况下检索它:成功登录后,他们将返回您的网站。
这些实现细节特定于身份提供者。如果他们使用 cookie,那么他们的工作就是实施反 CSRF 措施。他们比您使用有问题的第三方库或导入受损的外部组件的可能性要小得多,因为他们的应用程序只有一项工作。
如果这是一个非此即彼的命题,并且您有理由相信您的应用程序存在 XSS 或代码注入漏洞,那么这些漏洞绝对应该优先考虑。但良好的安全性需要遵循多个级别的最佳实践,以实现一种分层安全性。
另外,使用受信任的第三方库连接到受信任的第三方安全提供商应该有望节省您处理各种其他安全相关问题的时间。
| 归档时间: | 
 | 
| 查看次数: | 54694 次 | 
| 最近记录: |