Image

Json web token and its exploitation

  • Published On: May 12, 2022 Updated On: February 17, 2023

Contents

  • Origination
  • When should you use JSON Web Tokens?
  • What is JWT & how it can be exploited
  • JWT's Subsystems
  • Using a different bypassing approaches
  • Attacks against Json Web Tokens
  • Culmination

Origination

As an open standard, the JSON Web Token (JWT) defines a compact and self-contained method for securely transmitting information between parties as a JSON object (RFC 7519).

Because it has been digitally signed, this information can be trusted and verified. A secret (using the HMAC algorithm) or a public/private key pair (using RSA or ECDSA) can be used to sign JWTs.

In spite of the fact that JWTs are encryptable, we will only use signed tokens here.

Encrypted tokens, on the other hand, keep other parties from verifying the validity of claims contained within them. If a public/private key pair is used to sign a token, this signature also certifyes that only those who have access to the private key signed it.

When should you use JSON Web Tokens....?

Here are some scenarios where JSON Web Tokens are useful:

Authorization: This is the most common scenario for using JWT. Once the user is logged in, each subsequent request will include the JWT, allowing the user to access routes, services, and resources that are permitted with that token. Single Sign On is a feature that widely uses JWT nowadays, because of its small overhead and its ability to be easily used across different domains.

Information Exchange: JSON Web Tokens are a good way of securely transmitting information between parties. Because JWTs can be signed—for example, using public/private key pairs—you can be sure the senders are who they say they are. Additionally, as the signature is calculated using the header and the payload, you can also verify that the content hasn't been tampered with.

What is JWT - JSON web token & how it can be exploited.....?

JWT is a standard, meaning that all JWTs are tokens, but not all tokens are JWTs.

JWT is a open source service (API) that supports generating token based on client details and secret key.

Each JWT contains encoded JSON(JavaScript Object Notation) objects, including a set of claims.

Claims are used to transmit information between two parties.

JWTs are signed using a cryptographic algorithm to ensure that the claims cannot be altered after the token is issued.

JWTs are relatively small in size, a JWT can be sent through a URL, through a POST parameter, or inside an HTTP header, and it is transmitted quickly.

JSON

JSON stands for JavaScript Object Notation and is a text-based format for transmitting data across web applications.

It stores information in an easy-to-access manner, both for developers and computers.

It can be used as a data format by any programming language and is quickly becoming the preferred syntax for APIs, surpassing XML.

Token

A token is a string of data that represents something else, such as an identity.

In the case of authentication, a non-JWT-based token is a string of characters that allow the receiver to validate the sender’s identity.

A JWT is a string made up of three parts, separated by dots (.), and serialized using base64. In the most common serialization format, compact serialization, the JWT looks something like this: xxxxx.yyyyy.zzzzz

Example: The API consumer authenticates to the API provider with a username and password. The provider generates a JWT and sends it back to the consumer. The consumer adds the provided JWT to the Authorization header in all API requests.

JWT’s Subsystems

  • The header
  • The payload.
  • The signature.

image

The Header

The header contains metadata about the token, such as the algorithm used for the signature and the type of the token (which is simply JWT). For this example, the header before encoding is:

image

The most common algorithms used are HMAC and RSA algorithms.

The payload

The payload section contains the information that is actually used for access control. This section, too, is base64url encoded before being used in the token.

image

The signature

The signature is the part that is used to validate that the token has not been tampered with. It is calculated by concatenating the header with the payload, then signing with the algorithm specified in the header.image

The complete token

You get the complete token by concatenating each section (header, payload, and signature) with a “.” in between each section.

image

Using Different Bypassing Approaches

When implemented correctly, JSON web tokens provide a secure way to identify the user since the data contained in the payload section cannot be tampered But if implemented incorrectly, there are ways that an attacker can bypass the security mechanism and forge arbitrary tokens.

1.Failing to verify the signature

Many JWT libraries provide one method to decode the token and another to verify it:

decode(): Only decodes the token from base64url encoding without verifying the signature.

verify(): Decodes the token and verifies the signature.

Sometimes developers might mix up these methods. In that case, the signature is never verified and the application will accept any token (in a valid format). Developers might also disable signature verification for testing and then forget to re-enable it. Such mistakes could lead to arbitrary account access or privilege escalation.

For example, let’s say we have the following valid token that is never actually verified:

image

An attacker could send the following token with an arbitrary signature to obtain escalated privileges:

image

2. Allowing the None algorithm

   The JWT standard accepts many different types of algorithms to generate a signature:

    RSA

    HMAC

    Elliptic Curve

    None

The None algorithm specifies that the token is not signed. If this algorithm is permitted, we can bypass signature checking by changing an existing algorithm to None and stripping the signature.

image

Encoded and signed, the token will look like this (signature in bold):

image

If None is permitted as the algorithm value, an attacker can simply use it to replace the valid algorithm and then get rid of the signature:

image

Though now unsigned, the modified token will be accepted by the application:

image

Note : That is why it is important to not accept tokens with None, none, NONE, nOnE, or any other case variations in the alg header.

3. Changing the algorithm from RS256 to HS256

The algorithm HS256 uses a secret key to sign and verify each message.

The algorithm RS256 uses a private key to sign messages, and a public key to verify them.

If we change the algorithm from RS256 to HS256, the signature is now verified using the HS256 algorithm using the public key as secret key. Since the public key is not secret at all, we can correctly sign such messages.

Consider the following example code, which could be present at the server:

image

If the JWT uses asymmetric RS256,  this correctly verifies the signature on the token. If the JWT uses symmetric HS256, however, the signature is compared to a HMAC of the token, where the public_key is used as key. We can thus exploit this vulnerability by signing our own token using HS256 with the public key of the RS256 algorithm.

Attacks against JSON Web Tokens

1. Kid Parameter Manipulation

The JWT header can contain the Key Id parameter kid. It is often used to retrieve the key from a database or filesystem. The application verifies the signature using the key obtained through the kid parameter. If the parameter is injectable, it can open the way to signature bypass or even attacks such as RCE, SQLi, and LFI.

image

If the kid parameter is vulnerable to command injection, the following modification might lead to remote code execution:

image

2. kid parameter injection + directory traversal = signature   bypass

If an application uses the kid parameter to retrieve the key from the filesystem, it might be vulnerable to directory traversal.

Then an attacker can force the application to use a file whose value the attacker can predict as a key for verification. This can be done using any static file within the application. Knowing the key file value, the attacker can craft a malicious token and sign it using the known key. For example, an attacker might try to insert /dev/null as the key source to force the application to use an empty key

image

If directory traversal to /dev/null succeeds, the attacker will be able to sign a malicious token using an empty string.

Note: The same technique can be used with known static files, for example, CSS files.

3. Attacks using the jku header

In the JWT header, developers can also use the jku parameter to specify the JSON Web Key Set URL.

This parameter indicates where the application can find the JSON Web Key (JWK) used to verify the signature – basically the public key in JSON format.

For Example, let’s take the following JWT that uses the jku parameter to specify the public keyimage

The specified key.json file might look something like, The application verifies the signature using the JSON Web Key retrieved based on the jku header value:

image

Culmination

Authentication processes in modern web applications are becoming increasingly dependent on JSON Web Tokens. Instead of developing their own implementations of JWT.

Developers should follow best practices and use trusted JWT libraries. You should also use a high-quality vulnerability scanning solution to find weaknesses before they can be exploited by cybercriminals in order to minimize the risk of attackers chaining JWT attacks with other vulnerabilities.

JWT, like many other technologies, is fundamentally secure, but some implementations fail to meet this standard. The JWT may contain sensitive information, or it may be possible to change the signing algorithm, or the key used in the signature is insufficiently strong.