๋ณธ๋ฌธ์œผ๋กœ ๊ฑด๋„ˆ๋›ฐ๊ธฐ

JWT Security Vulnerabilities: Common Pitfalls and Exploitation Techniques

JSON Web Tokens (JWT) are everywhere in modern web applications. They're convenient, stateless, and easy to implement - which is exactly why they're often implemented wrong. Let's explore common JWT vulnerabilities you'll encounter in CTFs and real-world applications.

What Makes JWTs Vulnerable?โ€‹

JWTs consist of three parts: header, payload, and signature. The header and payload are base64-encoded JSON, while the signature validates the token's integrity. The problem? Developers often trust the header too much or validate the signature incorrectly.

The None Algorithm Attackโ€‹

The most famous JWT vulnerability is the "none" algorithm attack. Some JWT libraries allow the algorithm to be set to "none", effectively disabling signature verification.

How it works:

  1. Decode the JWT header and payload
  2. Modify the payload (change user ID, escalate privileges)
  3. Set the algorithm in the header to "none"
  4. Remove the signature
  5. Base64-encode and concatenate

In CTF challenges, this often looks like:

eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJ1c2VyIjoiYWRtaW4ifQ.

Notice the trailing period with no signature? That's your clue.

Algorithm Confusion: HS256 vs RS256โ€‹

This is a classic vulnerability that exploits the difference between symmetric (HS256) and asymmetric (RS256) algorithms.

The attack:

  • Server uses RS256 (public/private key pair)
  • Attacker changes algorithm to HS256
  • Server validates using the public key as the HMAC secret
  • Attacker signs the token with the public key (which they can obtain)

This works because the public key is, well, public. If the server doesn't properly enforce which algorithm to accept, you can trick it into using the public key as an HMAC secret.

Weak Secret Keysโ€‹

Many developers use weak secrets for signing JWTs. Tools like jwt_tool and hashcat can crack weak secrets through dictionary or brute-force attacks.

Common weak secrets:

  • "secret"
  • "password"
  • Empty string
  • Short numeric codes

In CTFs, always try cracking the JWT signature first. It's often the intended solution.

Key Injection via JKU/JWKSโ€‹

Some JWTs use the jku (JWK Set URL) or jwks (embedded JWK) header parameters to specify where to fetch the verification key. If the application doesn't validate the source:

  1. Create your own JWK Set
  2. Host it on your server
  3. Modify the JWT header to point to your malicious JWK URL
  4. Sign the token with your private key
  5. The server fetches your key and validates your forged token

Practical Tools for JWT Testingโ€‹

jwt_tool: Swiss Army knife for JWT testing. Automated scanning, token manipulation, and cracking.

python3 jwt_tool.py <JWT> -M at  # All tests mode
python3 jwt_tool.py <JWT> -C -d wordlist.txt # Crack

Burp Suite JWT Editor: Browser extension for manipulating JWTs in real-time during web app testing.

hashcat: For offline cracking of JWT secrets.

hashcat -a 0 -m 16500 jwt.txt wordlist.txt

Detection and Defenseโ€‹

For defenders:

  • Always validate the algorithm explicitly - never trust the header
  • Use strong, random secrets (minimum 256 bits for HS256)
  • Disable the "none" algorithm
  • Validate JKU/JWKS sources with a whitelist
  • Consider short expiration times
  • Don't store sensitive data in the payload (it's just base64!)

For bug hunters:

  • Check for algorithm confusion vulnerabilities
  • Attempt secret cracking with common wordlists
  • Look for JKU/JWKS manipulation opportunities
  • Test for missing expiration validation
  • Try the none algorithm (it still works sometimes!)

Conclusionโ€‹

JWTs are powerful but dangerous when misimplemented. Whether you're solving CTF challenges or performing security assessments, understanding these vulnerabilities gives you a significant advantage. The key is knowing that the JWT header is user-controlled data - and user-controlled data should never be trusted.

Happy hacking! ๐Ÿฅž