portswigger_AdvancedTopics
portswigger_AdvancedTopics
cvestone- Advanced topics
Advanced topics
JWT attacks
JWT攻击 In this section, we’ll look at how design issues and flawed handling of JSON web tokens (JWTs) can leave websites vulnerable to a variety of high-severity attacks. As JWTs are most commonly used in authentication, session management, and access control mechanisms, these vulnerabilities can potentially compromise the entire website and its users.
1 | 这部分,我们将专注于研究设计问题与jwt处理不当是如何导致网站受到高危攻击的。JWT普遍用于授权、会话管理与权限控制机制,这些漏洞能潜移默化地使整个网站与其用户被入侵。 |
Tip:From Burp Suite Professional 2022.5.1, Burp Scanner can automatically detect a number of vulnerabilities in JWT mechanisms on your behalf. For more information, see the related issue definitions on the Target > Issued definitions tab.
从Burp Suite Professional 2022.5.1开始,Burp扫描器能自动检测一定量的JWT机制漏洞。
What are JWTs?
什么是JWT? JSON web tokens (JWTs) are a standardized format for sending cryptographically signed JSON data between systems. They can theoretically contain any kind of data, but are most commonly used to send information (“claims”) about users as part of authentication, session handling, and access control mechanisms.
1 | JWT是一种标准格式,用于系统间发送加密且带签名的JSON数据。它们理论上包含各种类型数据,但它们是最普遍用于发送与用户相关的授权、会话处理与访问控制机制的信息(声明)。 |
Unlike with classic session tokens, all of the data that a server needs is stored client-side within the JWT itself. This makes JWTs a popular choice for highly distributed websites where users need to interact seamlessly with multiple back-end servers.
1 | 与传统session的值不同,所有服务器需要的数据都被存储在客户端的JWT自身当中。这使JWT成为当用户需要与多个后端服务器无缝交互的高分布式架构网站的首选。 |
That is, JWT is stateless for the server. The server does not need to save session information related to the user identity in memory or database as in the traditional way. Each token value of JWT contains all the necessary data. When verifying, the server only needs to check whether the signature is correct and whether the token is expired. 即JWT对于服务器来说是无状态类型的,服务器不需要像传统方式在内存或数据库里保存用户身份相关的session信息,JWT的每个token值自包含所有必要的数据,服务器验证时只需要检查签名是否正确,以及token是否过期等。
JWT format
JWT格式 A JWT consists of 3 parts: a header, a payload, and a signature. These are each separated by a dot, as shown in the following example:
1 | 一个JWT由三部分组成:header,payload,signature。它们由.隔开,正如下面的例子: |
eyJraWQiOiI5MTM2ZGRiMy1jYjBhLTRhMTktYTA3ZS1lYWRmNWE0NGM4YjUiLCJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJwb3J0c3dpZ2dlciIsImV4cCI6MTY0ODAzNzE2NCwibmFtZSI6IkNhcmxvcyBNb250b3lhIiwic3ViIjoiY2FybG9zIiwicm9sZSI6ImJsb2dfYXV0aG9yIiwiZW1haWwiOiJjYXJsb3NAY2FybG9zLW1vbnRveWEubmV0IiwiaWF0IjoxNTE2MjM5MDIyfQ.SYZBPIBg2CRjXAJ8vCER0LA_ENjII1JakvNQoP-Hw6GG1zfl4JyngsZReIfqRvIAEi5L4HV0q7_9qGhQZvy9ZdxEJbwTxRs_6Lb-fZTDpW6lKYNdMyjw45_alSCZ1fypsMWz_2mTpQzil0lOtps5Ei_z7mM7M8gCwe_AGpI53JxduQOaB5HkT5gVrv9cKu9CsW5MS6ZbqYXpGyOG5ehoxqm8DL5tFYaW3lB50ELxi0KsuTKEbD0t5BCl0aCR2MBJWAbN-xeLwEenaqBiwPVvKixYleeDQiBEIylFdNNIMviKRgXiYuAvMziVPbwSgkZVHeEdF5MQP1Oe2Spac-6IfA
The header and payload parts of a JWT are just base64url-encoded JSON objects. The header contains metadata about the token itself, while the payload contains the actual “claims” about the user. For example, you can decode the payload from the token above to reveal the following claims:
1 | header与payload部分是base64+url编码的JSON对象。header包含JWT自身的元数据,同时payload包含用户相关的“声明”(理解为用户相关的属性信息)。例如,你可以对来自上面JWT的payload进行解码从而揭示这些声明: |
{ "iss": "portswigger", "exp": 1648037164, "name": "Carlos Montoya", "sub": "carlos", "role": "blog_author", "email": "carlos@carlos-montoya.net", "iat": 1516239022 }
In most cases, this data can be easily read or modified by anyone with access to the token. Therefore, the security of any JWT-based mechanism is heavily reliant on the cryptographic signature.
1 | 多数情况下,这些数据很容易就能被任何拥有该token的人读取并修改它。因此,任何基于JWT机制的安全严重依赖于加密签名。 |
JWT signature
JWT签名 The server that issues the token typically generates the signature by hashing the header and payload. In some cases, they also encrypt the resulting hash. Either way, this process involves a secret signing key. This mechanism provides a way for servers to verify that none of the data within the token has been tampered with since it was issued:
1 | 发布token的服务器,通常给header与payload进行hash加密生成签名。在某些情况下,它们也加密hash后的结果。无论如何,这个过程涉及到一个签名私钥。这个机制为服务器提供一种验证token内部数据自发布以来是否被篡改的方法。 |
This is similar to the mechanism of using a specific hash value generated by a file to identify whether a file has been changed. 这和用文件生成的特定hash值来识别文件是否发生变更的机制有点像。
- As the signature is directly derived from the rest of the token, changing a single byte of the header or payload results in a mismatched signature.
1 | 因为签名是直接由JWT其他部分而衍生来的,改变一个字节的header或payload会使其变成无法匹配的签名。 |
- Without knowing the server’s secret signing key, it shouldn’t be possible to generate the correct signature for a given header or payload.
1 | 如果不知道服务器的签名私钥,不可能生成所给的header或payload相匹配的正确签名。 |
Tip:If you want to gain a better understanding of how JWTs are constructed, you can use the debugger on
jwt.io
to experiment with arbitrary tokens. 如果你想更好理解JWT的构成,你可以使用jwt.io
中的调试器测试任何token值。
JWT vs JWS vs JWE
The JWT specification is actually very limited. It only defines a format for representing information (“claims”) as a JSON object that can be transferred between two parties. In practice, JWTs aren’t really used as a standalone entity. The JWT spec is extended by both the JSON Web Signature (JWS) and JSON Web Encryption (JWE) specifications, which define concrete ways of actually implementing JWTs.
1 | JWT规范事实上非常有限。它只定义了一种用于表示信息(“声明”)的格式,作为一个能在双方之间传输的json对象。事实上,JWT不被用作为一个标准实体。JWT被JWS和JWE规范扩展,这定义了实际实现JWT的具体方式(理解为是一种接口)。 |
In other words, a JWT is usually either a JWS or JWE token. When people use the term “JWT”, they almost always mean a JWS token. JWEs are very similar, except that the actual contents of the token are encrypted rather than just encoded.
1 | 换句话说,JWT通常指的是JWS或JWE token。当人们用“JWT”专业术语,几乎总是指JWS token。JWE非常相似,只是token的实际内容是加密的,而不是仅仅编码。 |
Note:For simplicity, throughout these materials, “JWT” refers primarily to JWS tokens, although some of the vulnerabilities described may also apply to JWE tokens. 为了简化,在这些材料中,“JWT”主要指代 JWS 令牌,尽管描述的一些漏洞也可能适用于 JWE 令牌。
What are JWT attacks?
什么是JWT攻击? JWT attacks involve a user sending modified JWTs to the server in order to achieve a malicious goal. Typically, this goal is to bypass authentication and access controls by impersonating another user who has already been authenticated.
1 | JWT攻击指用户为了实现恶意目的,发送修改的JWT到服务器。通常这个目的是绕过身份认证与访问控制,通过冒充其他已经通过身份认证的用户来实现。 |
What is the impact of JWT attacks?
JWT攻击的影响是什么? The impact of JWT attacks is usually severe. If an attacker is able to create their own valid tokens with arbitrary values, they may be able to escalate their own privileges or impersonate other users, taking full control of their accounts.
1 | JWT攻击的影响通常很严重。如果黑客能用任意值创建他们自己的有效token,他们能够提升自身权限或冒充其他用户,完全掌控其账户。 |
How do vulnerabilities to JWT attacks arise?
JWT攻击漏洞是如何产生的? JWT vulnerabilities typically arise due to flawed JWT handling within the application itself. The various specifications related to JWTs are relatively flexible by design, allowing website developers to decide many implementation details for themselves. This can result in them accidentally introducing vulnerabilities even when using battle-hardened libraries.
1 | JWT漏洞通常由于应用内部的JWT处理缺陷而产生。各种与JWT相关的规范在设计上来说相对灵活,允许网站开发者自己决定许多实现细节。这可能导致意外地引入漏洞,即使使用的是经过(各种漏洞)锤炼过(修复过很多次)的库。 |
These implementation flaws usually mean that the signature of the JWT is not verified properly. This enables an attacker to tamper with the values passed to the application via the token’s payload. Even if the signature is robustly verified, whether it can truly be trusted relies heavily on the server’s secret key remaining a secret. If this key is leaked in some way, or can be guessed or brute-forced, an attacker can generate a valid signature for any arbitrary token, compromising the entire mechanism.
1 | 这些实现缺陷通常意味着JWT签名没有经过合适地验证。这使黑客能够通过篡改payload的值来传递给应用。即使签名被稳固地验证,但它是否能真正被信任强烈依赖于服务器的密钥(是否)依然保密。如果它的key因为某种方式被泄露了,或者能够猜出、暴力破解,黑客就能用任意token生成一个有效签名,让整个机制瓦解。 |
How to work with JWTs in Burp Suite
如何在Burp中运用JWT? In case you haven’t worked with JWTs in the past, we recommend familiarizing yourself with the relevant features of Burp Suite before attempting the labs in this topic.
1 | 如果曾经你没使用过JWT,尝试实验室之前,我们推荐你自己先去试下相关的Burp功能。 |
Read more
Working with JWTs in Burp Suite
You can use Burp Inspector to view and decode JWTs. You can then use the JWT Editor extension to:
1 | 您可以使用 Burp Inspector 查看和解码 JWT。然后您可以使用 JWT 编辑器扩展来: |
- Generate cryptographic signing keys.
- Edit the JWT.
- Resign the token with a valid signature that corresponds to the edited JWT.
1 | 1. 生成加密签名keys |
You can follow along with the process below using our JWT authentication bypass via unverified signature lab.
Before you start
Install the JWT Editor extension. For more information, see Installing extensions from the BApp Store.
Viewing JWTs
查看JWT
- Identify a request with a JWT that you want to investigate further. Look for the highlighted requests in Proxy > HTTP history, these are automatically flagged by the JWT Editor extension.
1 | 1.识别出一个你想进一步调查的JWT请求。在Proxy > HTTP history查看高亮请求,这些已经由该拓展自动标注出来了。 |
2. To view the JWT contents, highlight sections of
the token in turn. Notice that the content is automatically decoded in
the Inspector panel.
1 | 2.为了查看JWT内容,转到高亮的token部分。注意到内容在Inspector中被自动解码了。 |
3. Review the contents of the JWT in
the Inspector panel, to identify interesting
information and determine any modifications that you want to make.
1 | 3. 在该面板中预览JWT内容,识别有趣的信息,确定任何你想对其做的更改。 |
Editing JWTs
编辑JWT To edit a JWT using the JWT Editor
extension:
为了使用该拓展编辑JWT:
- Right-click the request with the JWT and select Send to Repeater.
- In the request panel, go to the JSON Web Token tab.
- Edit the JSON data as required in the Header and Payload fields.
- Click Sign. A new dialog opens.
- In the dialog, select the appropriate signing key, then click OK. The JWT is re-signed to correspond with the new values in the header and payload. If you haven’t added a signing key, follow the instructions below.
1 | 1. 右键JWT请求,选择发送至重放器 |
This process is actually to simulate the server to generate a specific secret key, then encrypt and re-sign the header and payload, as mentioned above: 这个过程实际上就是在模拟服务器生成特定密钥key,然后对header与payload进行加密并重新签名,如上面说的:
Adding a JWT signing key
添加JWT签名密钥 To add a signing key to Burp using
the JWT Editor extension:
为了使用该拓展添加签名key到Burp:
- Go to the JWT Editor Keys tab.
- Click the button for the type of key that you want to add. For example, New Symmetric Key. A new dialog opens.
- In the dialog, add the new key:
- Click Generate to create a new key.
- Alternatively, paste an existing key into the dialog.
- Edit the key as required.
- Click OK to save the key.
1 | 1. 前往JWT Editor Keys标签 |
The signing key type of the JWT added here should be consistent with the type selected in the above editing step, mainly to prepare for the subsequent forgery of JWT. But please note that, looking back at the previous content, all the signing keys mentioned here must be valid, that is, they must be consistent with the key generated by the target server, mainly through Leak/Brute, etc. Otherwise, the fabricated key cannot be used. 这里添加JWT的签名密钥类型,和上面编辑步骤时选择的类型要一致,主要就是为后续伪造JWT做准备。但注意,回顾前面内容,这里提到的所有signing key,必须是有效的,即必须与目标服务器生成该key时是一致的,主要通过泄露/爆破等方式。否则,凭空捏造的key是无法利用的。
Exploiting flawed JWT signature verification
利用冒充的JWT签名认证 By design, servers don’t usually store any information about the JWTs that they issue. Instead, each token is an entirely self-contained entity. This has several advantages, but also introduces a fundamental problem - the server doesn’t actually know anything about the original contents of the token, or even what the original signature was. Therefore, if the server doesn’t verify the signature properly, there’s nothing to stop an attacker from making arbitrary changes to the rest of the token.
1 | 根据设计,服务器通常不存储任何JWT相关的发布信息。反而,每个token是一个完整的自包含式实体(不需要服务器存储其信息)。这有一些好处,但会引起一种根本问题 - 服务器事实上不知道任何关于该token的原本内容,甚至原来的签名也不知道。因此,如果服务器没有适当地校验签名,没有什么能够阻止黑客构造任意变更,从而对token的剩余部分造成影响。 |
In other words, the ability for hackers to impersonate JWT signatures is closely related to the entity characteristics of the token value in JWT and the server’s processing mechanism for JWT, which is a natural condition. But please note that portswigger’s description here is easy to cause misunderstanding. In fact, when the JWT is first generated, the server must know the content of its token. It’s just that the subsequent JWT is stateless for the server. The server will not save the source JWT after the first signature. After receiving the JWT, it needs to re-parse and verify its signature(There is no way to compare with the source token in the traditional way). Therefore, if the server is not rigorous in verification (for example, using the unsafe algorithm none, or not doing JWT identity matching, etc.), when the hacker tampers with the JWT to bypass it, it is equivalent to taking advantage of the server’s verification flaws, that is, the integrity of the JWT cannot be guaranteed (as defined in CIA). 也就是说,能够让黑客实现冒充JWT签名,和JWT中token值自身的实体特点与服务器对JWT的处理机制是脱不开关系的,是天然条件。但注意portswigger这里的描述容易让人产生误解,实际上刚开始生成JWT时,服务器肯定是知道其token内容的,只是由于后续JWT对于服务器是无状态的,服务器第一次签名之后就不会保存该源JWT,后续接收到JWT后需要重新解析和验证其签名(没办法像传统方式和源token进行比对),所以如果服务器校验时不严谨(比如使用不安全算法none,或者没有做JWT的身份匹配等),当黑客篡改JWT后实现绕过,就相当于利用了服务器的校验缺陷,即无法保证JWT的完整性(CIA中的定义)。
For example, consider a JWT containing the following claims:
1 | 例如,考虑一个包含下面声明的JWT: |
{ "username": "carlos", "isAdmin": false }
If the server identifies the session based on
this username
, modifying its value might enable an attacker
to impersonate other logged-in users. Similarly, if
the isAdmin
value is used for access control, this could
provide a simple vector for privilege escalation.
1 | 如果服务器基于这个username做鉴别,修改该值可能使黑客冒充已登录用户。类似地,如果isAdmin值被用于权限控制,这可能为权限提升提供了简单的攻击向量(即攻击条件,这是常见的专业术语)。 |
In the first couple of labs, you’ll see some examples of how these vulnerabilities might look in real-world applications.
Analogy Understanding: JWT can be compared to a security check: 1. Issuing a check: When the bank (server) issues a check, it will record the amount, the payee and affix an anti-counterfeiting seal (signature). 2. Verify the check: When the payee goes to the bank to cash it, the bank does not compare the original check in the database, but checks whether the security seal is valid. 3. Vulnerability risk: If the bank does not check the security seal (signature), the attacker can modify the amount of the check at will, and the bank will accept it unconditionally. 类比理解: 可以将JWT类比为防伪支票: 1. 签发支票:银行(服务器)签发支票时,会记录金额、收款人并加盖防伪印章(签名)。 2. 验证支票:收款人去银行兑现时,银行不会对比数据库中的原始支票,而是检查防伪印章是否有效。 3. 漏洞风险:如果银行不检查防伪印章(签名),攻击者可以随意修改支票金额,银行会无条件接受。
Therefore, the core contradiction of the JWT vulnerability problem is that the convenience brought by statelessness vs the security of complete dependence on signature verification. If the validation logic is not perfect, the server will not be able to perceive whether the JWT has been tampered with or not, because there is no stored “truth” to compare to. Rigor of the validation phase determines the reliability of the JWT 所以,JWT漏洞问题的**核心矛盾在于:无状态性带来的便利性 vs 完全依赖签名验证的安全性。若验证逻辑不完善,服务器将无法感知JWT是否被篡改,因为没有任何存储的“真相”可供比对。验证阶段的严格性决定了JWT的可靠性**
Accepting arbitrary signatures
接收任意签名 JWT libraries typically provide one
method for verifying tokens and another that just decodes them. For
example, the Node.js
library jsonwebtoken
has verify()
and decode()
.
1 | JWT库通常提供一种方法来验证token,另一种方法只是将它们解码。例如, |
Occasionally, developers confuse these two methods and only pass
incoming tokens to the decode()
method. This effectively
means that the application doesn’t verify the signature at all.