JWT attacks | Web Security Academy Labs

JWT (JSON Web Token) attacks are commonly employed in authority and authentication scenarios. They are utilized for securely transmitting cryptographically signed JSON data. In this context, all data is stored client-side, considered secure due to cryptographic signing – meaning the server remains unaware of the original JWT.

Format

JWTs consist of three parts: header, payload, and signature, each separated by a dot. Each part is base64url encoded.

  • Header: Metadata about the token that can be decoded.
  • Payload: Claims about the user that can be decoded.
  • Signature: A hash of the above two to indicate that they haven’t been interfered with.

To hack a JWT (JWS), one needs to figure out how to generate the signature after tampering with the body/header. A useful site for decoding JWTs is CyberChef.

Assumptions

Several assumptions are made:

  • JWT isn’t being verified.
  • The server accepts unsigned JWTs.
  • Brute-forcing the key is possible.
  • Embedding our JWK is feasible.
  • Modifying the JKU header to point to our domain is allowed.
  • Modifying the KID to a known file on the local server (/dev/null) is feasible.

JWT Auth Bypass via Unverified Sign

Relying on the server using decode() but not verify(), sending an unverified JWT. Tamper by replacing the payload.

json

{ "iss": "portswigger", "sub": "administrator", "exp": 1704159614 }

JWT Auth Bypass via Flawed Sign Verification (Unsecured JWT)

Each token is a self-contained entity, so the server lacks knowledge about the JWT. In this attack, the alg parameter is set to none, i.e., unsecured JWT. It’s crucial to note that token rejection at this point usually occurs via string parsing, making obfuscation viable (mixed caps, unexpected encodings, etc.). Tamper by modifying the body payload, setting the alg header to “none,” and removing the signature.

JWT Auth Bypass via Weak Signing Key

Brute-forcing is attempted using hashcat.

JWT Auth Bypass via JWK Header Injection

The JWK parameter is used to embed the correct verification key in the token. It doesn’t check whether the key comes from a trusted source. JWK follows a standardized format: kty, e, kid, and n. In this lab, generating a private key and using it to sign the JWT is required.

JWT Authentication Bypass via JKU Header Injection

JKU (JWK Set URL) in the JWT header is a URL from which the key is retrieved without checking whether the provided URL belongs to a trusted domain. JKU sets are sometimes exposed publicly via endpoints like /.well-known/jwks.json. These domain URLs could be filtered, so using the “@” character or “#” for a URL fragment is suggested.

JWT Authentication Bypass via KID Header Path Traversal

KID can be an arbitrary string, so point at a local file whose contents are known (usually ../../dev/null) and sign it using an empty string. alg needs to be symmetrical (e.g., HS256).

JWT Authentication Bypass via Algorithm Confusion

Algorithm should be verified via private key, but confusion is introduced by tampering the header so it assumes a public key (symmetric). Obtain the server’s public key exposed via a standard endpoint (/jwks.json). Convert the public key to the correct format (JWK to PEM).

NOTE: It must be identical to the public key on the server.

Leave a Comment