第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定

瀏覽器中存儲訪問令牌的最佳實踐

本文由 Curity 的 Judith Kahrer 撰写,最初发布在 The New Stack

Web 应用程序不是静态网站,而是静态和动态内容的精心组合。通常情况下,Web 应用程序的逻辑在浏览器中运行。应用程序不会从服务器获取所有内容,而是通过在浏览器中运行的 JavaScript 从后端 API 获取数据,并相应地更新 Web 应用程序的呈现。

为了保护数据的访问,组织应该使用OAuth 2.0。使用OAuth 2.0时,JavaScript应用程序需要在每个对API的请求中添加访问令牌。出于易用性的原因,JavaScript应用程序通常不会在需要时请求访问令牌,而是将其存储起来。问题在于,如何在JavaScript中获取这样的访问令牌?当获取到令牌后,应用程序应该将令牌存储在哪里,以便在需要时将其添加到请求中?

本文讨论了在浏览器中可用的不同存储解决方案,并强调了每种选项相关的安全风险。在审查了这些威胁之后,它描述了一个解决方案,即一种模式,为必须与OAuth保护的API集成的JavaScript应用程序提供了最佳的浏览器安全选项。

获取访问令牌

在应用程序可以存储访问令牌之前,它需要先获取一个。当前最佳实践推荐了一种获取访问令牌的方法:代码流。代码流是一个两步流程,首先从用户那里收集授权许可——授权码。然后,应用程序通过一个后端请求将授权码交换为访问令牌。这个请求称为令牌请求,如下例所示:

注意,任何人都可以检查浏览器加载的资源,包括任何JavaScript代码。因此,任何用JavaScript实现的OAuth客户端都被视为公共客户端——无法保密,因此在令牌请求期间无法进行身份验证。然而,代码交换证明密钥(PKCE)为公共客户端提供了保护授权码流程的方法。为了降低与授权码相关的风险,始终在授权码流程中使用PKCE。

浏览器威胁
跨站请求伪造 (CSRF)

跨站请求伪造(CSRF)攻击中,恶意攻击者会诱使用户无意中通过浏览器执行恶意请求。例如,攻击者可能在网站中嵌入一个经过精心设计的图片src字符串,从而触发浏览器执行GET请求,或者在恶意网站上添加一个表单,触发POST请求。在任何情况下,浏览器可能会自动将cookie添加到这些请求中,包括单点登录(SSO)的cookie。

CSRF 攻击也被称为“会话骑行”,因为攻击者通常利用用户的已认证会话来发起恶意请求。因此,攻击者可以默默地代表用户执行请求,并调用用户可以调用的任何端点。然而,攻击者无法读取响应,所以他们通常会瞄准一次性的、改变状态的请求,比如更新用户的密码。

跨站脚本攻击 (XSS)

跨站脚本攻击 (XSS) 漏洞允许攻击者在原本受信任的网站中注入恶意的客户端代码。漏洞可能出现在任何用户输入生成输出且未进行适当清理的地方。浏览器会自动在受信任网站的上下文中运行恶意代码。

XSS 攻击可以用来窃取访问和刷新令牌,或者执行 CSRF 攻击。不过,XSS 攻击有一个时间窗口,因为它们只能在有限的时间内运行,比如在令牌的有效期内,或者在存在漏洞的标签页打开期间。

即使在XSS无法用于获取访问令牌的情况下,攻击者也可能利用XSS漏洞通过会话骑行向受保护的web端点发送经过身份验证的请求。攻击者可以冒充用户,调用用户可以调用的任何后端端点,并造成严重损害。

浏览器中的存储解决方案

当应用程序接收到访问令牌时,需要将令牌存储起来以便在API请求中使用。用户浏览器中有多种方式可以持久化数据。应用程序可以使用专用API,例如Web Storage API或IndexedDB来存储令牌。应用程序也可以简单地将令牌保留在内存中或将它们放在cookie中。一些存储机制是持久化的,而其他机制在一段时间后、页面关闭或刷新时会被清除。

一些解决方案会在不同标签页之间共享数据,而其他解决方案仅限于当前标签页。然而,本指南中介绍的大多数方法是按源存储数据的。因此,对于任何相关讨论来说,理解一些概念是有益的:源和站点。

某些(网页)资源的来源是其 URL 的方案、主机名和端口。例如,https://example.com/number/onehttps://example.com:80/path/two 具有相同的来源,因为它们共享相同的方案(https)和主机名(example.com),以及端口(默认端口)。它们的来源是 https://example.com,这与 https://example.com:8443https://this.example.com 不同,因为它们在端口和主机名上有所不同。

相比之下,一个网站比资源的来源更大。网站是提供一组资源的网络应用程序的通用名称。简单来说,网站是指方案和域名,例如 https://example.com。虽然 https://example.comhttps://this.example.com:8443 的来源不同(主机名和端口不同),但它们是同一个网站,因为它们托管在相同的域名(example.com)并且使用相同的方案(https)。(从技术上讲,这个定义有一些细微差别,但这个简化说明有助于解释概念)。

本地存储

本地存储通过JavaScript中的全局localStorage对象,经由Web Storage API进行访问。存储在本地存储中的数据可以在浏览器的各个标签页和会话之间共享,这意味着数据不会过期,也不会在浏览器关闭时被删除。因此,通过localStorage存储的数据可以在应用程序的所有标签页中访问。因此,人们往往会倾向于将令牌存储在localStorage中。

每当应用程序调用API时,它会从存储中获取令牌并手动添加到请求中。然而,由于本地存储可以通过JavaScript访问,这意味着此解决方案也容易受到跨站脚本攻击(XSS)。

如果你使用 localStorage 来保存访问令牌,并且攻击者能够在你的应用程序中运行外来 JavaScript 代码,攻击者可以窃取任何令牌并直接调用 API。此外,XSS 还允许攻击者操纵应用程序的本地存储数据,这意味着攻击者可以更改令牌。

请注意,本地存储中的数据会永久保存,这意味着存储在其中的任何令牌都会保留在用户的设备(笔记本电脑、计算机、移动设备或其他设备)文件系统中,并且即使浏览器关闭后,其他应用程序也可以访问这些令牌。因此,在使用 localStorage 时,请考虑端点安全性。注意并防范浏览器外部的攻击向量,例如恶意软件、被盗设备或磁盘。

根据上述讨论,遵循以下建议:

  • 不要在本地存储中存储敏感数据,如令牌。
  • 不要信任本地存储中的数据(尤其是不要信任用于身份验证和授权的数据)。
会话存储

会话存储是Web Storage API提供的另一种存储机制。与本地存储不同,使用sessionStorage对象存储的任何数据在关闭标签页或浏览器时都会被清除。此外,会话存储中的数据在其他标签页中是不可访问的。只有当前标签页和源中的JavaScript代码可以读取和写入相同的会话存储。

会话存储比本地存储更安全,因为浏览器会在窗口关闭时自动移除任何令牌,因此不会留下任何静止的令牌。此外,由于会话存储在不同标签页之间是不共享的,攻击者无法从另一个标签页(或窗口)读取令牌,从而减少了跨站脚本攻击的影响。

在实践中,使用 sessionStorage 存储令牌时的主要安全顾虑是 XSS。如果您的应用程序容易受到 XSS 攻击,攻击者可以从中提取令牌并重新使用它进行 API 调用。因此,会话存储不适合存储诸如令牌之类的敏感数据。

IndexedDB

IndexedDB 是索引数据库API的简称。它是一种在浏览器中异步存储大量数据的API。然而,在存储令牌时,通常不需要该浏览器API提供的特性和容量。由于应用程序在每个API调用中都会发送令牌,因此最好将令牌的大小保持在最小。

与前面讨论的其他客户端存储机制一样,使用Indexed Database API存储的数据也受到同源策略的限制。只有同源的资源和服务工作者才能访问这些数据。从安全角度来看,IndexedDB与本地存储类似:

  • 令牌可能会通过文件系统泄漏。
  • 令牌可能会通过 XSS 攻击泄漏。

因此,不要在 IndexedDB 中存储访问令牌或其他敏感数据。IndexedDB 更适合存储应用程序离线运行所需的数据,例如图片。

内存中

一种相当安全的存储令牌的方法是将其保留在内存中。与其它方法相比,令牌不会存储在文件系统中,因此可以减轻与设备文件系统相关的风险。

最佳实践建议在内存中存储令牌时将其放在一个闭包中。例如,你可以定义一个单独的方法来使用令牌调用API。这样不会将令牌泄露给主应用程序(主线程)。下面的摘要展示了如何使用JavaScript在内存中处理令牌的一个示例。

注意,攻击者在获取到令牌后可能无法直接访问该令牌,因此可能无法直接使用令牌调用API。即便如此,他们可以通过持有令牌引用的 apiClient 在任何时候调用API。然而,任何此类攻击都仅限于标签页打开的时间段以及接口提供的功能范围内。

除了可能存在的XSS漏洞带来的安全问题外,将令牌保留在内存中还有一个很大的缺点,那就是在页面刷新时令牌会被丢弃。应用程序随后必须获取一个新的令牌,这可能会触发新的用户认证。一个安全的设计应该考虑到用户体验。

一种使用服务工作者的架构通过在与主网页分离的单独线程中运行令牌处理功能来缓解可用性问题。服务工作者实际上充当了应用程序、浏览器和网络之间的代理。因此,它们可以拦截请求和响应,例如缓存数据并启用离线访问,或获取和添加令牌。

当使用JavaScript闭包或Service Worker来处理令牌和API请求时,XSS攻击可能会针对OAuth流程,例如回调或静默流程,以获取令牌。它们可能会注销并绕过任何Service Worker,或者通过重写方法如window.fetch来“实时读取令牌”,从而实现原型污染。因此,虽然可以考虑使用JavaScript闭包和服务工作者来提高便利性,但不应依赖它们来保证安全性。

Cookies

Cookie 是存储在浏览器中的数据片段。按照设计,浏览器会在每次请求服务器时添加 Cookie。因此,应用程序必须谨慎使用 Cookie。如果不仔细配置,浏览器可能会在跨站请求中附加 Cookie,从而允许跨站请求伪造(CSRF)攻击。

Cookie 有一些属性来控制它们的安全性。例如,SameSite 属性可以帮助减轻 CSRF 攻击的风险。当一个 Cookie 的 SameSite 属性设置为 Strict 时,浏览器会将该 Cookie 添加到那些起源于与 Cookie 来源相同的站点并且目标也是该站点的请求中。当请求嵌入到任何第三方站点(如通过链接)时,浏览器不会添加这些 Cookie。

你可以通过JavaScript设置和获取cookie。然而,当使用JavaScript读取cookie时,应用程序会变得容易受到XSS(以及CSRF)攻击的影响。因此,更推荐的做法是让后端组件来设置cookie,并将其标记为HttpOnly。这个标志通过指示浏览器cookie不能通过JavaScript访问,从而减轻了通过XSS攻击泄露数据的风险。

为了防止通过中间人攻击泄露cookie,从而导致会话劫持,cookie应该仅通过加密连接(HTTPS)发送。为了指示浏览器仅在HTTPS请求中发送cookie,cookie必须设置Secure属性。

Set-Cookie:token=myvalue;SameSite=Strict;Secure;HttpOnly

与浏览器中的任何其他永久存储解决方案一样,cookie 可能会在浏览器关闭后仍然保留在文件系统中(例如,cookie 不必过期,或者浏览器可能会将 session cookie 作为恢复会话功能的一部分保留)。为了降低从文件系统泄露 token 的风险,只应在 cookie 中存储加密后的 token。因此,后端组件必须仅在 Set-Cookie 标头中返回加密后的 token。

威胁矩阵

下表总结了浏览器中存储解决方案的安全评估,主要威胁向量用红色标记。橙色威胁需要超出网页技术所能提供的措施来缓解。绿色威胁可以通过正确的设置成功消除。

每当攻击者成功窃取到令牌时,他们可以一直使用有效的访问令牌,而无需用户的配合。如果攻击者能够窃取到刷新令牌,他们可以显著延长攻击时间并增加损害,因为他们可以刷新访问令牌。黑客甚至可能将攻击扩展到除JavaScript应用程序使用的API之外的其他API。例如,攻击者可以尝试重放访问令牌并利用不同API中的漏洞。

被盗的访问令牌可能会造成重大损害,而XSS仍然是Web应用程序的主要担忧。因此,避免将访问令牌存储在客户端代码可以访问的地方。相反,将访问令牌存储在cookie中。当使用适当的属性配置时,浏览器不会通过cookie泄露访问令牌。此时,XSS攻击就相当于在同一站点上的会话劫持攻击。

使用 Cookies 的 OAuth 语义

Cookie仍然是传输令牌并作为API凭证的最佳选择,因为即使攻击者成功利用了XSS漏洞,也无法从Cookie中获取访问令牌。然而,为了确保这一点,Cookie必须正确配置。

首先,将 cookies 标记为 HttpOnly,以确保它们不可通过 JavaScript 访问,从而应对 XSS 攻击的风险。另一个重要的属性是 Secure 标志,它确保 cookies 只能通过 HTTPS 发送,以减轻中间人攻击的风险。

其次,发放仅几分钟有效的短期访问令牌。在最坏的情况下,最小生命周期的访问令牌也只能被滥用一段可以接受的短时间。通常认为15分钟的有效时间是合适的。让cookie和令牌在大约相同的时间失效。

第三,将令牌视为敏感数据。仅将加密后的令牌存储在 cookies 中。如果攻击者设法获取了加密后的令牌,他们将无法从中解析任何数据。攻击者也无法将加密后的令牌重放给其他 API,因为其他 API 无法解密该令牌。加密后的令牌仅限定了被盗令牌的影响。

第四,限制发送API凭证的时机。仅将凭证发送到需要API凭证的资源。这意味着确保浏览器仅在实际需要访问令牌的API调用中添加凭证。为此,凭证需要有适当的设置,例如 SameSite=Strict,指向API端点域名的域属性以及路径。

最后,在使用刷新令牌时,确保将其存储在单独的 cookie 中。无需在每个 API 请求中都发送刷新令牌,因此请确保不会这样做。刷新令牌仅在刷新过期的访问令牌时才需要添加。这意味着存储刷新令牌的 cookie 的设置与存储访问令牌的 cookie 的设置略有不同。

令牌处理模式

令牌处理程序模式是一种设计模式,它结合了JavaScript客户端中OAuth的最佳实践原则。它遵循了后端为前端(BFF)的方法,如OAuth 2.0 for Browser-Based Apps中所述。该模式引入了一个后端组件,能够颁发包含加密令牌及其必要属性的cookie,如上所述。

后端组件的责任是:

  • 作为OAuth客户端与授权服务器交互,发起用户认证并获取令牌。
  • 管理JavaScript应用程序的令牌,确保其不可访问。
  • 代理并拦截所有API请求,附加正确的访问令牌。

令牌处理程序模式定义了一个 BFF,该 BFF 为在浏览器中运行的应用程序抽象了 OAuth。换句话说,令牌处理程序模式建议了一个 API,JavaScript 应用程序可以使用该 API 来认证用户并安全地调用经过身份验证的 API。为此,该模式使用 cookie 来存储和发送访问令牌。

令牌处理程序是一个后端组件,它可以例如驻留在API网关中。它由两部分组成:

  • OAuth Agent,负责处理OAuth流程以从授权服务器获取令牌。
  • OAuth Proxy,拦截对API的所有请求并将cookie转换为令牌。

OAuth Agent 获取到令牌后,会发放具有以下属性的 cookies:

  • SameSite=Strict
  • HttpOnly
  • Secure
  • API 的路径

由于Token Handler是一个后端组件,OAuth Agent是一个保密客户端,可以向授权服务器进行身份验证(与JavaScript客户端这种公开客户端相比)。这意味着为了获取令牌,OAuth Agent需要进行身份验证。因此,攻击者需要获取客户端凭证才能成功获取新令牌。在JavaScript中运行无声流程而没有客户端凭证将会失败。

为了使 token handler 模式生效,JavaScript 应用程序和 Token Handler 组件必须部署在同一站点上(换句话说,它们必须运行在同一个域名下)。否则,由于 cookie 的同站点限制,浏览器将不会将 token cookie 添加到 API 请求中。

为了获取数据,JavaScript 应用程序通过 OAuth 代理调用 API:

浏览器会自动将 cookies 添加到请求中。在上面的例子中,浏览器会在跨源请求中包含 cookies。然而,由于 cookie 属性 SameSite=Strict,浏览器只会将 cookies 添加到同一站点(同一域名)的跨源请求中。

OAuth 代理解密 cookies 并将 token 添加到上游 API。cookie 属性确保浏览器仅将 cookies 添加到 HTTPS 请求中,从而确保它们在传输过程中是安全的。由于 tokens 是加密的,因此它们在静止状态下也是安全的。然后使用这些 tokens 来安全地访问 API。

结论

API 访问最好通过 OAuth 和访问令牌来保护。然而,JavaScript 应用程序在这方面处于不利地位。在浏览器中安全地存储令牌没有解决方案。所有现有的解决方案在某种程度上都容易受到 XSS 攻击。因此,保护任何应用程序的首要任务应该是防止 XSS 漏洞。

令牌处理程序模式通过将加密的令牌存储在任何 JavaScript 都无法访问的 cookie 中来缓解 XSS 风险。它将 Web 关注点与 API 关注点分离,并提供了使用成熟 Web 技术加强 JavaScript 应用程序的指导,而不损害 Web 架构。查看 令牌处理程序模式的详细描述探索各种示例

點擊查看更多內(nèi)容
TA 點贊

若覺得本文不錯,就分享一下吧!

評論

作者其他優(yōu)質(zhì)文章

正在加載中
  • 推薦
  • 評論
  • 收藏
  • 共同學(xué)習(xí),寫下你的評論
感謝您的支持,我會繼續(xù)努力的~
掃碼打賞,你說多少就多少
贊賞金額會直接到老師賬戶
支付方式
打開微信掃一掃,即可進行掃碼打賞哦
今天注冊有機會得

100積分直接送

付費專欄免費學(xué)

大額優(yōu)惠券免費領(lǐng)

立即參與 放棄機會
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號

舉報

0/150
提交
取消