Disclosing a New Vulnerability in JWT Secret Poisoning (CVE-2022-23529)
2023-1-9 22:0:49 Author: unit42.paloaltonetworks.com(查看原文) 阅读量:74 收藏

A pictorial representation of the JsonWebToken vulnerability.

Executive Summary

Unit 42 researchers discovered a new vulnerability in the popular JsonWebToken open source project. The vulnerability is identified as CVE-2022-23529, rated high severity (CVSS 7.6).

By exploiting this vulnerability, attackers could achieve remote code execution (RCE) on a server verifying a maliciously crafted JSON web token (JWT) request. If you are using JsonWebToken package version 8.5.1 or an earlier version, please update to JsonWebToken package version 9.0.0, which includes a patch for this vulnerability.

JsonWebToken is an open source JavaScript package that allows you to verify/sign JWTs, which are mainly used for authorization and authentication purposes. Developed and maintained by Auth0, the package had over 9 million weekly downloads at the time of writing, and over 20,000 dependents (according to the JsonWebToken page). This package plays a big role in the authentication and authorization functionality for many applications.

Palo Alto Networks customers can identify assets that are running vulnerable versions of the JsonWebToken package with Prisma Cloud, and they can identify the relevant CVE within scan results.

Related Unit 42 Topics  CVE-2022-23529, remote code execution, open source, cloud

JWT 101
How Does the Authentication Process Work?
JWT and Open Source
The Vulnerability (CVE-2022-23529)
JsonWebToken Fix
Disclosure Process

JWT 101

JWT (pronounced “jot”) is an open standard that defines a method of transferring information securely by encoding and signing JSON data. JWTs have a string structure that consists of 3 parts separated by a dot (.):


JWTs are used to transmit different types of information, but are mainly used to deliver “claims,” which are pieces of information about some subject. In practice, this will most likely contain useful information about a user.

The most common use case of JWTs is for authorization and authentication. Let’s quickly go over the JWT structure.

JWT Header

As shown in Figure 1, the header consists mostly of two parameters that indicate the type of the token and the signing algorithm.

Image 1 is a screenshot of two lines of code enclosed in curly brackets. The first line is “alg: HS256” and the second line is “top” JWT.”
Figure 1. JWT header.

JWT Payload

The payload (shown in Figure 2) is the second part of the token, which will contain the claims. In most cases, this will provide useful information about a user.

Image 2 is a screenshot of two lines of code enclosed in curly brackets. The first line is “user_name: John Doe” and the second line is “admin: true.”
Figure 2. JWT payload.

There are three different types of claims: registered, public and private. You can find more information about them in RFC 7519.

The header and payload are each Base64Url encoded to form the first and second parts of a JWT string:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 and eyJ1c2VyX25hbWUiOiJKb2huIERvZSIsImFkbWluIjp0cnVlfQ.

The third part of the JWT, the signature, is then computed (signed) by the following formula using a secret key. A signature is used to verify that the token isn’t forged or manipulated. Because it is signed with a secret key, we can validate the authenticity of the sender:

base64Url(HMACSHA256( base64Url(header) + ”.” + base64Url(payload), secret_key)) = epQym-1JoN9eep458VBZw4-cVhwfmsI1cfaGa6PE818

Putting it all together, we will get a JWT in its complete form, as shown in Figure 3.

Image 3 is a screenshot of a JSON web token string with the different parts, header, payload and signature red, green and cyan respectively.
Figure 3. Full JSON web token.

How Does the Authentication Process Work?

Let’s take a look at a simple authentication process using a JSON web token (also shown in Figure 4):

  1. To access a protected resource, the user will log in using credentials, usually username and password.
  2. A request containing this information will be sent to the authentication endpoint.
  3. An authentication server will validate the information sent within a request and issue a JWT signed with a secret key, which can be stored on a server or in a different location using a secret manager.
  4. From now on, each user request will contain a JWT in the authorization header. This way, users with the right permissions can receive access to protected resources.
  5. When a user requests access to a protected resource, a request containing a JWT will be generated from the application to the JWT authentication endpoint.
  6. Before the user receives access to a requested resource, the JWT that was sent in the authorization header will be verified using the secret key. This is done to verify it was not tampered with along the way and that the user has the right permissions to view the requested information. If secret keys are not stored securely, an attacker who can control the secret key will be able to execute code on a host verifying JWT.
Image 4 is a diagram showing the process of JWT authentication, starting with the user and their credentials. After access is granted and the gateway authenticates the JWT, a secret key is fetched for verification from the key manger and the poisoned secret is present.
Figure 4. Diagram of the process of authentication with JWT.

JWT and Open Source

Open source projects help a lot of organizations to save time and other resources. At times, this can serve as an elegant and quick problem solver. JWTs became a very popular technology that many organizations rely on, and this is one of the reasons that some of the open source projects implementing JWTs have become a great success.

One such project is a well-known JavaScript solution for signing, verifying and decoding JWTs named JsonWebToken. This tool is developed and maintained by Auth0, part of Okta.

The Vulnerability (CVE-2022-23529)

Typically, attacks on JWTs will involve different forgery techniques abusing buggy JWT implementations. These kinds of attacks have severe consequences because, in most cases, a successful attack allows an attacker to bypass authentication and authorization mechanisms to access confidential information or steal and/or modify data.

One of the methods provided by the JsonWebToken package is verify. The verify method receives three parameters: token, secretOrPublicKey and options. This function verifies the validity of the JWT and returns the decoded payload part.

According to the documentation, secretOrPublicKey is a string or buffer. We can see the lines of code shown in Figure 5 in the JsonWebToken verify.js source code.

Image 5 is a screenshot of 4 lines of code taken from verify.js showing the secretOrPublicKey.
Figure 5. Code snippet from verify.js.

When no allowed algorithms are provided within the options algorithms list, the values within the privacy enhanced mail (PEM) file, which is provided by the secretOrPublicKey parameter, will be assigned instead. This presents a problem: There is no check in place in order to determine that secretOrPublicKey is indeed a string or a buffer (per the documentation), and it’s blindly using its toString() method.

Let's observe the following, shown in Figure 6, using node.js (a JavaScript runtime environment) version 18.9.1.

Image 6 is a screenshot of 4 lines of code which shows the creation of a buffer object in node.js.
Figure 6. Creating a buffer object.

We see that the buffer we created is of the type: object. Now let’s find out, using JsonWebToken package version 8.5.1, what will happen if we pass a malicious object to the verify function via the secretOrPublicKey parameter and override its toString() method.

Image 7 is a screenshot of many lines of code where the researchers use JsonWebToken to execute a verify function with a malicious object.
Figure 7. Arbitrary write file PoC.

By executing the verify function with a malicious object, we succeeded in writing an arbitrary file on the hosting machine.

At this stage, secretOrPublicKey is receiving the value of mal_obj, which is a malicious object with an overridden toString() function. The new toString() function is logging PWNED!!! into the node console and exiting the node process by triggering our “on exit” event listener writeFileSync() function, which is writing an arbitrary file on the hosting machine.

As shown in Figure 8, verify.js line 114 is triggering our payload when calling the toString() function.

Image 8 is a screenshot of 2 lines of code showing where line 114 triggers the payload when calling the toString() function.
Figure 8. Line 114 from verify.js.

Our malicious code will execute and exit the node process before the .includes(‘BEGIN CERTIFICATE’)check, resulting in an arbitrary write file.

Image 9 is a screenshot of the title bar and contents of an arbitrary write file. The file name is “malicious.text” and the text is “PWNED! ! ! ! Arbitrary File Write on the host machine.”
Figure 9. PoC result, file created.

With the same technique, it is possible to achieve RCE, but we will have to slightly modify our payload by using the child_process module (as shown in Figure 10).

Image 10 is a screenshot of 3 lines of code where the payload has been modified using the child_process module.
Figure 10. RCE PoC.


In the previous section, we demonstrated how a poisoned secret key could lead to RCE. In reality, keeping and maintaining secret keys involves best practices such as using secret managers and secret key rotations, as well as encryption, etc.

With that being said, in order to exploit the vulnerability described in this post and control the secretOrPublicKey value, an attacker will need to exploit a flaw within the secret management process. Thus, due to the complexity of this vulnerability, we suggested a CVSS score of 7.6 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:H/A:L using the CVSS 3.1 model.

JsonWebToken Fix

JsonWebToken version 9.0.0 contains the following fix:

Image 11 is a screenshot of multiple lines of code. It is the JsonWebToken patch released with version 9.0.0 where checks for the type of secretOrPublickey are now in place.
Figure 11. Patch.

The vulnerable code was removed and replaced with checks for the type of secretOrPublickey parameter, which prevents secretOrPublicKey from containing malicious objects.

Disclosure Process

  • July 13, 2022 – Unit 42 researchers sent a disclosure to the Auth0 team under responsible disclosure procedures
  • July 27, 2022 – Auth0 team updated that the issue was under review
  • Aug. 23, 2022 – Unit 42 researchers sent an update request
  • Aug. 24, 2022 – Auth0 team updated that the engineering team was working on the resolution
  • Dec. 21, 2022 – A patch was provided by the Auth0 engineering team

Open source projects are commonly used as the backbone of many services and platforms today. This is also true for the implementation of sensitive security mechanisms such as JWTs, which play a huge role in authentication and authorization processes.

Security awareness is crucial when using open source software. Reviewing commonly used security open source implementations is necessary for maintaining their dependability, and it's something the open source community can take part in.

As part of the commitment of Palo Alto Networks to open source software security, we regularly conduct security research efforts that include identifying security vulnerabilities in open source projects.

Palo Alto Networks Prisma Cloud customers can detect affected images and hosts under the Vulnerabilities tab. The platform detects JsonWebToken packages and alerts on entities running with a vulnerable version. In addition, our users can search for CVE-2022-23529 in the Vulnerability Explorer section to discover more details about the vulnerability and assets affected by it.

We would like to thank the Auth0 team for professionally handling the disclosure process and providing a patch for the reported vulnerability.

Get updates from
Palo Alto

Sign up to receive the latest news, cyber threat intelligence and research from us

文章来源: https://unit42.paloaltonetworks.com/jsonwebtoken-vulnerability-cve-2022-23529/