✪ All about JWT attacks (tools included) !!!

@fuffsec
5 min readOct 10, 2022

--

Photo by Ferhat Deniz Fors on Unsplash

JWT is a token system that was originally created to make it possible to verify authorization. Although this may be used for authentication in some circumstances. They are built on the JSON format and contain a token signature to guarantee the token’s integrity.

Today, we’ll discuss the security risks associated with utilizing JSON web tokens (and signature-based tokens in general), as well as how attackers might use them to get around access restriction.

How it works

A JSON web token consists of 3 components: a header, a payload, and a signature.

and, it looks something like this,

The header

The header section of a JSON web token identifies the algorithm used to generate the signature. It is encoded in base64url.

The Payload

The payload section contains the information that is actually used for access control. It is also base64url encoded.

The signature

The signature is the part that is used to validate that the token has not been tampered with. (Integrity)

Let’s get started with the interesting part.

Photo by Manja Vitolic on Unsplash

Attack

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. None algorithm

JWT supports a “none” algorithm. If the alg field is set to “none”, any token would be considered valid if their signature section is set to empty.

{
"alg" : "none",
"typ" : "JWT"
}
{
"user" : "victim"
}

2. Accepting arbitrary signatures

Sometimes, developers may miss to check the signature. Hence, we can tamper the payload and send it.

3. Brute-forcing secret keys

If the developer uses weak or know secret keys, then we can bruteforce with tools such as hashcat or JohnTheRipper.

you can use the following wordlist for the operation 🐱‍💻.

https://github.com/wallarm/jwt-secrets/blob/master/jwt.secrets.list

hashcat -a 0 -m 16500 [jwt] [wordlist]

4. JWT algorithm confusion | key confusion attack

Algorithm confusion attacks (also known as key confusion attacks) occur when an attacker is able to force the server to verify the signature of a JSON web token using a different algorithm than is intended by the website’s developers. If this case isn’t handled properly, this may enable attackers to forge valid JWTs containing arbitrary values without needing to know the server’s secret signing key.

5. Header Injection

According to the JWS specification, only the alg header parameter is mandatory. In practice, however, JWT headers (also known as JOSE headers) often contain several other parameters. The following ones are of particular interest to attackers.

  • jwk (JSON Web Key) - Provides an embedded JSON object representing the key.
  • jku (JSON Web Key Set URL) - Provides a URL from which servers can fetch a set of keys containing the correct key.
  • kid (Key ID) - Provides an ID that servers can use to identify the correct key in cases where there are multiple keys to choose from. Depending on the format of the key, this may have a matching kid parameter.

jwk Injection

According to the JSON Web Signature (JWS) specification, servers can utilize the optional `jwk` header argument to embed their public key right into the token itself in JWK format. Servers should ideally only validate JWT signatures using public keys from a small whitelist. However, incorrectly configured servers occasionally utilize any key that is included in the jwk argument.

jku Injection

Some servers permit you to reference a JWK Set containing the key instead of embedding public keys directly using the jwk (JWK Set URL) header option. The server gets the necessary key from this URL and uses it to validate the signature.

kid Injection

Servers may use several cryptographic keys for signing different kinds of data, not just JWTs. For this reason, the header of a JWT may contain a kid (Key ID) parameter, which helps the server identify which key to use when verifying the signature.

Verification keys are often stored as a JWK Set. In this case, the server may simply look for the JWK with the same kid as the token. However, the JWS specification doesn't define a concrete structure for this ID - it's just an arbitrary string of the developer's choosing. For example, they might use the kid parameter to point to a particular entry in a database, or even the name of a file.

Hence, there is a possibility for SSRF, XXE, SQL Injection

Let’s Automate….

Tools

Run jwt_tool with mode All Tests! and wait for green lines

python3 jwt_tool.py -M at \
-t "https://api.example.com/api/v1/user/76bab5dd-9307-ab04-8123-fda81234245" \
-rh "Authorization: Bearer eyJhbG...<JWT Token>"

If you are lucky the tool will find some case where the web application is correctly checking the JWT:

Then, you can search the request in your proxy or dump the used JWT for that request using jwt_ tool:

python3 jwt_tool.py -Q “jwttool_706649b802c9f5e41052062a3787b291”

How to prevent JWT attacks

  • Use an up-to-date library for handling JWTs and make sure your developers fully understand how it works, along with any security implications.
  • Make sure that you perform robust signature verification on any JWTs that you receive, and account for edge-cases such as JWTs signed using unexpected algorithms.
  • Enforce a strict whitelist of permitted hosts for the jku header.
  • Make sure that you’re not vulnerable to path traversal or SQL injection via the kid header parameter.

--

--

@fuffsec

Threat Researcher | (OSEP, OSWE, OSCP, OSWA, OSWP, CRTP, eWPTX, SSCP)