浏览器中存储访问令牌的最佳实践

浏览器提供了各种持久化数据的解决方案 。当存储令牌时 , 您应该权衡存储选择与安全风险 。

浏览器中存储访问令牌的最佳实践

文章插图
译自Best Practices for Storing Access Tokens in the Browser 。
web应用程序不是静态站点,而是静态内容和动态内容的精心组合 。更常见的是,web应用程序逻辑在浏览器中运行 。与从服务器获取所有内容不同,应用程序在浏览器中运行JAVAScript,从后端API获取数据,并相应地更新web应用程序呈现 。
为了保护数据访问,组织应该采用OAuth 2.0 。通过OAuth 2.0 , JavaScript应用程序需要在对API的每个请求中添加访问令牌 。出于可用性原因,JavaScript应用程序通常不会按需请求访问令牌 , 而是存储它 。问题是,如何在JavaScript中获取这样的访问令牌?当您获取一个令牌时,应用程序应该在哪里存储令牌,以便在需要时将其添加到请求中?
本文讨论了浏览器中可用的各种存储解决方案,并突出了与每种选择相关的安全风险 。在审查威胁之后,它描述了一种解决方案,以提供最佳的浏览器安全选项,用于必须与OAuth保护的API集成的JavaScript应用程序 。
获取访问令牌在应用程序可以存储访问令牌之前 , 它需要先获取一个令牌 。当前的最佳实践建议通过“授权码流”这一方式来获取访问令牌: 授权码流是一个两步流程,首先从用户那里收集一个授权许可——授权码,然后应用程序在后台通道中用授权码交换访问令牌 。这个请求称为令牌请求 , 例子如下:
const accessToken = awAIt fetch(OAuthServerTokenEndpoint, {method: "POST",// token request with authorization code and PKCE// submits data in as x-www-form-urlencoded encoded formatbody: new URLSearchParams({ client_id: "example-client",grant_type: "authorization_code",code: authorization_code, code_verifier: pkce_code_verifier})})// server responds with JSON object.then (response => response.json()).then (tokenResponse => {// parse access token from responseif (tokenResponse.accessToken) {return tokenResponse.accessToken;} // else handle error response}).catch( // handle.NETwork error)请注意,任何人都可以检查浏览器加载的资源,包括任何JavaScript代码 。因此,任何用JavaScript实现的OAuth客户端都被认为是一个公开客户端——一个无法保密的客户端,因此在令牌请求期间无法进行身份验证 。然而 , 代码交换的证明密钥(Proof Key for Code Exchange,PKCE)提供了一种方法来确保公开客户端的授权码流的安全性 。为了减轻与授权码相关的风险 , 在使用授权码流时,始终应用PKCE 。
浏览器威胁跨站请求伪造(CSRF)在跨站请求伪造(CSRF)攻击中,恶意行为者会欺骗用户通过浏览器无意中执行恶意请求 。例如,攻击者可以在网站中嵌入精心设计的图像源字符串,以触发浏览器运行GET请求,或者在恶意网站上添加表单,以触发POST请求 。在任何情况下,浏览器都可能会自动将cookie(包括单点登录cookie)添加到这样的请求中 。
CSRF攻击也被称为“会话骑乘”,因为攻击者通常会利用用户的经过身份验证的会话来进行恶意请求 。因此,攻击者可以默默地代表用户执行请求,并调用用户可以调用的任何端点 。然而,攻击者无法读取响应,所以他们通常以一次性状态更改请求为目标,如更新用户的密码 。
跨站脚本(XSS)跨站脚本(XSS)漏洞允许攻击者将恶意的客户端代码注入到一个本来受信任的网站中 。例如,如果用户输入生成的输出没有被适当清理,web应用程序的任何地方都可能存在漏洞 。浏览器会自动在受信任的网站的上下文中运行恶意代码 。
XSS攻击可用于窃取访问令牌和刷新令牌,或执行CSRF攻击 。不过,XSS攻击有一个时间窗口,因为它们只能在有限的时间段内运行,如令牌的有效期内,或者打开的选项卡存在漏洞的时长 。
即使在XSS无法用于检索访问令牌的情况下,攻击者也可以利用XSS漏洞通过会话骑乘向有保护的Web端点发送经过身份验证的请求 。然后,攻击者可以伪装成用户,调用用户可以调用的任何后端端点,并造成严重损害 。
浏览器中的存储解决方案应用程序收到访问令牌后,需要存储该令牌以在API请求中使用它 。浏览器中有多种方法可以持久化数据 。应用程序可以使用专用API(如Web存储API或IndexedDB)来存储令牌 。应用程序也可以简单地将令牌保存在内存中或将其放在cookie中 。一些存储机制是持久的,另一些在一段时间后或页面关闭或刷新后会被清除 。


推荐阅读