Agent skill

jwt-attack-surface

Audit JWT implementation for algorithm confusion, secret weakness, claim validation issues, and token handling vulnerabilities. Use when reviewing authentication systems using JWT.

Stars 163
Forks 31

Install this agent skill to your Project

npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/data/jwt-attack-surface

SKILL.md

JWT Attack Surface Audit

Purpose

Identify JWT implementation vulnerabilities including algorithm confusion, weak secrets, missing validation, and token handling issues.

Focus Areas

  • Algorithm Confusion: alg=none, RS256→HS256 confusion
  • Weak Secrets: Short/guessable HMAC secrets
  • Missing Validation: Signature bypass, claim verification
  • Token Handling: Storage, transmission, revocation
  • Claim Issues: Expiration bypass, privilege escalation

Critical Vulnerabilities

Algorithm None Attack

javascript
// VULNERABLE - accepts "alg": "none"
jwt.verify(token, secret, { algorithms: ['HS256', 'none'] });

// SECURE - explicit algorithm whitelist
jwt.verify(token, secret, { algorithms: ['HS256'] });

RS256 to HS256 Confusion

python
# If server uses RS256 (asymmetric):
# - Attacker gets public key
# - Signs token with public key using HS256
# - Server verifies with public key as HMAC secret

# VULNERABLE - accepts multiple algorithms
jwt.decode(token, public_key, algorithms=['RS256', 'HS256'])

# SECURE - single algorithm only
jwt.decode(token, public_key, algorithms=['RS256'])

Weak HMAC Secret

javascript
// VULNERABLE - short/guessable secret
const secret = "secret123";
jwt.sign(payload, secret);

// SECURE - strong random secret (>= 256 bits)
const secret = crypto.randomBytes(64).toString('hex');

Missing Expiration Check

go
// VULNERABLE - ignoring exp claim
claims, _ := jwt.Parse(token, keyFunc)
// No expiration validation!

// SECURE - validate expiration
claims, err := jwt.ParseWithClaims(token, &Claims{}, keyFunc)
if err != nil || claims.ExpiresAt.Before(time.Now()) {
    return ErrExpired
}

Output Format

yaml
findings:
  - title: "JWT accepts 'none' algorithm"
    severity: critical
    attack_scenario: "Attacker crafts unsigned JWT with alg=none, bypasses authentication"
    preconditions: "None"
    reachability: public
    impact: "Complete authentication bypass"
    confidence: high
    cwe_id: "CWE-327"
    affected_assets:
      - "src/auth/jwt.rs:45"
      - "/api/auth/verify"

Audit Checklist

Token Generation

[ ] Secret is cryptographically random (>= 256 bits)
[ ] Algorithm is explicitly set (not from token)
[ ] Claims include: iat, exp, iss, aud
[ ] Expiration is reasonable (< 24h for access tokens)
[ ] Sensitive data not in payload (use references)

Token Verification

[ ] Algorithm whitelist (single algorithm preferred)
[ ] Signature verification BEFORE parsing claims
[ ] Expiration (exp) validated
[ ] Issuer (iss) validated
[ ] Audience (aud) validated
[ ] Not-before (nbf) validated if present

Token Handling

[ ] Stored in httpOnly cookie (not localStorage)
[ ] Transmitted over HTTPS only
[ ] Revocation mechanism exists
[ ] Refresh token rotation implemented
[ ] Token not leaked in URLs/logs

Attack Scenarios

1. None Algorithm

Header: {"alg": "none", "typ": "JWT"}
Payload: {"sub": "admin", "role": "admin"}
Signature: (empty)

2. Key Confusion (RS256→HS256)

# Get public key from /api/.well-known/jwks.json
# Sign with public key using HS256
# Server uses public key as HMAC secret

3. Weak Secret Brute Force

# Tools: hashcat, jwt_tool
hashcat -m 16500 jwt.txt wordlist.txt

4. Claim Tampering

# Modify claims if signature not verified
{"sub": "user", "role": "user"} → {"sub": "admin", "role": "admin"}

Severity Guidelines

Issue Severity
alg=none accepted Critical
Algorithm confusion possible Critical
Weak/guessable secret Critical
No signature verification Critical
No expiration validation High
Token in URL/logs High
No issuer/audience validation Medium
Token in localStorage Medium
Long expiration (> 24h) Low

KYCo Integration

Register JWT implementation vulnerabilities:

1. Check Active Project

bash
kyco project list

2. Register Finding

bash
kyco finding create \
  --title "JWT accepts 'none' algorithm" \
  --project PROJECT_ID \
  --severity critical \
  --cwe CWE-327 \
  --attack-scenario "Attacker crafts unsigned JWT with alg=none, bypasses authentication" \
  --impact "Complete authentication bypass" \
  --assets "src/auth/jwt.rs:45,/api/auth/verify"

3. Import Scanner Results

bash
# Import semgrep JWT rules
semgrep --config p/jwt --sarif -o jwt-audit.sarif .
kyco finding import jwt-audit.sarif --project PROJECT_ID

Common CWE IDs for JWT Issues

  • CWE-327: Use of Broken or Risky Cryptographic Algorithm
  • CWE-287: Improper Authentication
  • CWE-347: Improper Verification of Cryptographic Signature
  • CWE-798: Use of Hard-coded Credentials (weak secret)
  • CWE-613: Insufficient Session Expiration

Didn't find tool you were looking for?

Be as detailed as possible for better results