我目前正在使用ReactJS构建一个单页应用程序。
我读到不使用localStorage的原因之一是因为XSS漏洞。
既然React会转义所有用户输入,那么现在使用localStorage是否安全呢?
我目前正在使用ReactJS构建一个单页应用程序。
我读到不使用localStorage的原因之一是因为XSS漏洞。
既然React会转义所有用户输入,那么现在使用localStorage是否安全呢?
当前回答
Philippe De Ryck博士写了一篇有用的文章,深入分析了漏洞(尤其是XSS)的真正影响。
这篇文章让人大开眼界!
简而言之,开发人员最关心的应该是保护web应用程序不受XSS的影响,而不应该太担心使用哪种类型的存储区域。
菲利普医生建议采取以下3个步骤:
Don't worry too much about the storage area. Saving an access token in localStorage area will save the developer a massive amount of time for development of next phases of the application. Review your app for XSS vulnerabilities. Perform a through code review and learn how to avoid XSS within the scope of your templating framework. Build a defense-in-depth mechanism against XSS. Learn how you could further lock down your application. E.g. utilising Content Security Policy (CSP) and HTML5 sandboxing.
记住,一旦你被XSS攻击了,游戏就结束了!
其他回答
看待这个问题的一种方法是考虑风险或伤害的水平。
你是否正在创造一款没有用户的应用,即POC/MVP?你是一家需要快速进入市场并测试应用程序的初创公司吗?如果是,我可能只会实施最简单的解决方案,并继续专注于寻找适合市场的产品。使用localStorage,因为它通常更容易实现。
你是在开发一款拥有大量日活跃用户的应用的v2版本,还是一款人们/企业非常依赖的应用?被黑客攻击是否意味着几乎没有恢复空间?如果是这样,我会仔细研究一下您的依赖关系,并考虑将令牌信息存储在仅http的cookie中。
使用localStorage和cookie/session存储都有各自的优缺点。
正如第一个答案所述:如果您的应用程序有XSS漏洞,那么两者都不能保护您的用户。由于大多数现代应用程序都有十几个或更多不同的依赖项,因此越来越难以保证应用程序的某个依赖项不受XSS攻击。
如果您的应用程序确实存在XSS漏洞,并且黑客已经能够利用它,那么黑客将能够代表您的用户执行操作。黑客可以通过从localStorage检索令牌来执行GET/POST请求,或者如果令牌存储在http-only cookie中,则可以执行POST请求。
在本地存储中存储令牌的唯一缺点是黑客将能够读取您的令牌。
基本上可以将JWT存储在localStorage中。
我认为这是一个好方法。 如果我们谈论的是XSS, XSS使用CDN,这也是一个潜在的风险,获得您客户的登录/通行证。将数据存储在本地至少可以防止CSRF攻击。
你需要了解这两点,然后选择你想要的。这两种攻击都不是你所需要注意的,只要记住:你的整个应用程序的安全性仅与你的应用程序的最不安全的点一样。
再次重申,存储是OK的,易受XSS, CSRF,…不是
Philippe De Ryck博士写了一篇有用的文章,深入分析了漏洞(尤其是XSS)的真正影响。
这篇文章让人大开眼界!
简而言之,开发人员最关心的应该是保护web应用程序不受XSS的影响,而不应该太担心使用哪种类型的存储区域。
菲利普医生建议采取以下3个步骤:
Don't worry too much about the storage area. Saving an access token in localStorage area will save the developer a massive amount of time for development of next phases of the application. Review your app for XSS vulnerabilities. Perform a through code review and learn how to avoid XSS within the scope of your templating framework. Build a defense-in-depth mechanism against XSS. Learn how you could further lock down your application. E.g. utilising Content Security Policy (CSP) and HTML5 sandboxing.
记住,一旦你被XSS攻击了,游戏就结束了!
我加入讨论的时间比较晚,但是由于OpenID Connect等更成熟和现代的认证协议的优势。
TL;DR:首选的方法是将JWT Token存储在内存中:而不是在cookie中,也不是在本地存储中。
细节
您希望将用户身份验证的责任与应用程序的其他工作分离开来。Auth很难得到正确的答案,少数几个花了所有时间思考这个问题的团队可能会担心你我永远都不会得到正确答案的细节。
为你的应用建立一个专用的身份提供者,并使用OpenID Connect协议进行身份验证。这可能是像谷歌、Microsoft或Okta这样的提供商,也可能是与一个或多个其他服务联合的轻量级身份服务器。
使用授权码流让用户验证并获得应用程序的访问令牌。使用一个受尊重的客户端库来处理OpenID连接细节,这样你就可以让库在应用程序拥有有效令牌、通过刷新获得新的有效令牌或当令牌无法刷新(因此用户需要再次验证)时通知应用程序。应该对库进行配置(可能是默认情况),以避免存储令牌。
FAQ
当有人刷新页面时会发生什么?我不想让他们再次登录。
When the app first loads, it should always redirect the user to your Identity Provider. Based on how that identity provider handles things, there's a good chance the user won't have to log in. For example, if you're federating to an identity provider like Google or Microsoft, the user may have selected an option indicating that they are on a trusted device and they want to be remembered. If so, they won't need to log in again for a very long time, long after your auth token would have expired. This is much more convenient for your users.
同样,如果用户表示他们在共享设备上,将来不应该自动登录,那么您希望强制再次登录:您无法区分刷新浏览器窗口的用户和重新打开关闭的浏览器并导航到存储在浏览器历史记录中的页面的用户。
身份提供者不是使用cookie来保持用户登录吗?那么CSRF或XSS攻击呢?
这些实现细节是特定于身份提供程序的。如果他们使用cookie,他们的工作就是实施反csrf措施。他们比你更不可能使用有问题的第三方库,或者导入有问题的外部组件,因为他们的应用程序只有一个任务。
难道我不应该花时间解决XSS攻击吗?如果有人向我的应用程序中注入代码,这难道不是“游戏结束”吗?
如果这是一个非此即彼的命题,并且你有理由相信你的应用程序存在XSS或代码注入漏洞,那么这些肯定应该优先考虑。但是,对于一种分层的安全性来说,良好的安全性包括在多个级别上遵循最佳实践。
此外,使用受信任的第三方库连接到受信任的第三方安全提供者应该有望节省您处理各种其他安全相关问题的时间。
我对所有建议不要存储在本地存储的答案感到不安,因为这很容易受到XSS攻击或恶意库的攻击。其中一些问题甚至会进入冗长的讨论,尽管答案非常小/简单,我很快就会讲到。
这就相当于说:“不要用煎锅做饭,因为如果你某天晚上喝醉了,决定用煎锅做饭,你会把自己和房子都烤焦的。” 如果jwt由于XSS攻击或恶意库而泄露,那么站点所有者就有更大的问题:他们的站点容易受到XSS攻击或正在使用恶意库。
答案是:如果你确信你的网站不存在这些漏洞,那就去做吧。
裁判:https://auth0.com/docs/security/data-security/token-storage # browser-local-storage-scenarios