JWT
JSON Web Token

Read this article first:
JWT.IO - JSON Web Tokens Introduction
JSON Web Tokens Introduction - JWT.IO
JWT is similar to a session token, but they work differently:
  • A session token contains only the session ID. The client sents this session token to the server and server looks up this ID in its database. This backend database stores all the information regarding the user's session, for example, username, authorization, and etc.
  • A JWT contains the entire session object and it is stored on the client side. JWT consists of a signature so the server can verify its integrity.
To summarize, with session ID cookies, sessions live on the server, but with JWTs, sessions live on the client.

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.
Here decode() does NOT verify the signature at all. Sometimes developers might mix up these methods.

If the none algorithm is accepted by the server, then the signature won't be verified at all. That is, anyone can forge a malicious JWT and the server will accept it blindly. This is a dumb vulnerability, just disable the none algorithm, please.

With symmetric encryption, a cryptographic signature is only as strong as the secret used.
If an application uses a weak secret, the attacker can simply brute-force it by trying different secret values until the original signature matches the forged one. Having discovered the secret, the attacker can use it to generate valid signatures for malicious tokens. To avoid this vulnerability, strong secrets must always be used with symmetric encryption.

JWT accepts both symmetric and asymmetric encryption algorithms. Depending on the encryption type, you need to use either a shared secret or a public-private key pair:
Algorithm
Key used to sign
Key used to verify
Asymmetric (RSA)
Private key
Public key
Symmetric (HMAC)
Shared secret
Shared secret
When an application uses asymmetric encryption, it can openly publish its public key and keep the private key secret. This allows the application to sign tokens using its private key and anyone can verify this token using its public key. The algorithm confusion vulnerability arises when an application does not check whether the algorithm of the received token matches the expected algorithm.
In many JWT libraries, the method to verify the signature is something like verify() which takes two arguments depending on user-specified algorithm:
  • verify(token, secret) – if the user-specified algorithm is HS256
  • verify(token, public_key) – if the user-specified algorithm is RS256
Unfortunately, in some libraries, verify() does NOT check whether the received token is signed using the application's expected algorithm. Suppose the server uses RS256. If the public key is accessible within the application, an attacker can forge malicious tokens by:
  1. 1.
    Changing the algorithm of the token to HS256
  2. 2.
    Tampering with the payload to get the desired outcome
  3. 3.
    Signing the malicious token with the public key found in the application
  4. 4.
    Sending the JWT back to the application
The application expects RSA encryption, so when an attacker supplies HMAC instead, the verify() method will treat the public key as an HMAC shared secret and use symmetric rather than asymmetric encryption. This means that the token will be signed using the application’s non-secret public key and then verified using the same public key.
To avoid this vulnerability, applications must check if the algorithm of the received token is the expected one before they pass the token to the verify() method.

In RSA || HMAC Confusion, the attacker needs the public key to exploit the vulnerability. What if the attacker does not have the public key? Bad luck, it is still vulnerable. Read this article to learn more:
Abusing JWT public keys without the public key
Silent Signal Techblog
Abusing JWT public keys without the public key

CryptoHack – Crypto on the Web challenges
CryptoHack
Crypto on the Web - CryptoHack

Critical vulnerabilities in JSON Web Token libraries
Auth0 - Blog
Critical vulnerabilities in JSON Web Token libraries
JSON Web Token attacks and vulnerabilities
netsparker
JSON Web Token attacks and vulnerabilities
Copy link
On this page
What is JWT?
Vulnerability 1: decode() || verify()
Vulnerability 2: The "None" Algorithm
Vulnerability 3: HS256 Weak Secret
Vulnerability 4: RSA || HMAC Confusion
Vulnerability 5: RSA || HMAC Confusion without Public Key
Lab
Reference