SecurityClaw Got Admin Access in 0.16 Seconds — Without Touching the Password

· SecurityClaw Demo D19 · API Security

JWT authentication is supposed to be cryptographically secure. The AcmeCorp API Gateway issued tokens signed with HS256. SecurityClaw's jwt-tool campaign found the signing secret in 0.16 seconds and achieved full admin access via algorithm bypass in under 200ms — without knowing the password, without sending a login request, without touching any credential at all. Four vulnerabilities confirmed. Two critical. Here's every step.

Date:March 22, 2026
Tool:jwt-tool
Category:API Security
Result:✅ Pass — 4/4 vulnerabilities confirmed (2 CRITICAL, 2 MEDIUM)
Target:AcmeCorp API Gateway (Flask, controlled test environment)
Methodology note: This is a controlled demo against a sandboxed AcmeCorp API Gateway (Flask) built by Peng's SecurityClaw research team with deliberate JWT vulnerabilities representative of real-world misconfigured implementations. The demo target has 18/18 TDD tests passing — the vulnerabilities are intentional and verified correct before campaign. Running JWT attacks against APIs you don't own is illegal. This demo exists to show defenders what broken JWT implementations look like from the attacker's perspective. Demo D19 — SecurityClaw's API Security category. Campaign 33.

The Full Vulnerability Table

ID Severity Vulnerability Impact
JWT-02 CRITICAL alg:none accepted — unsigned token Full admin access with zero credential knowledge, <200ms
JWT-01 CRITICAL Weak HMAC signing secret Secret cracked in 0.16s — arbitrary token forgery
JWT-03 MEDIUM No exp claim Stolen tokens valid indefinitely — no forced re-authentication
JWT-04 MEDIUM Sensitive data in payload (password hash) Password hash readable by any party that touches the token

Attack 1: alg:none — Admin Access in Under 200ms (JWT-02)

Alice logs in. The server issues a JWT. The token is three Base64-encoded segments separated by dots: header.payload.signature. The header names the signing algorithm. The payload contains Alice's identity and role. The signature is the cryptographic proof that the server issued it.

Here's what SecurityClaw did:

# Step 1: Alice's legitimate token
Header:  {"alg": "HS256", "typ": "JWT"}
Payload: {"sub": "alice", "role": "user", "email": "alice@acmecorp.com"}
→ Valid HS256 signature appended

# Step 2: Decode the payload (no crypto — it's just Base64)
# Modify: "role": "user"  →  "role": "admin"

# Step 3: Set alg to "none" — remove signature entirely
Header:  {"alg": "none", "typ": "JWT"}
Payload: {"sub": "alice", "role": "admin", "email": "alice@acmecorp.com"}
Signature: (empty)

# Step 4: Submit the unsigned token to /api/admin/users
→ HTTP 200: {"users": [...], "admin_access": true}

Time elapsed: under 200ms

The server accepted the token. It saw alg:none in the header, skipped signature verification (as the JWT spec technically permits for unsecured tokens), read role:admin from the payload, and returned the admin user list.

No password. No brute force. No network noise beyond a single HTTP request. The entire "authentication" collapsed because the server didn't explicitly reject the algorithm value that means "trust me, no signature needed."

"The most dangerous JWT vulnerability isn't a flaw in the cryptography — it's trusting a value the attacker controls that tells you to skip the cryptography."

Attack 2: Weak Secret Cracked in 0.16 Seconds (JWT-01)

The alg:none bypass requires the server to accept unsigned tokens. Not every broken implementation goes that far. But there's a second path that requires nothing more than the token itself: cracking the signing secret offline.

jwt-tool campaign output:
[*] Testing jwt-common.txt (common JWT/API secrets wordlist)...
[+] Found matching key: secret123

Time to crack: 0.16 seconds

secret123 is the signing key. It's in jwt-common.txt — a short wordlist of the most commonly used JWT secrets found in public repositories, hardcoded in tutorials, and leaked in breach data. It's also in rockyou.txt. Every credential-cracking tool on earth would find it.

With the signing key recovered, SecurityClaw forged a new token:

# Forge admin token, signed with the recovered secret
jwt-tool --sign secret123 --payload '{"sub": "alice", "role": "admin"}'
→ Valid HS256 token — server accepts as legitimate

# Submit to /api/admin/users
→ HTTP 200: admin endpoint returns full user list

The server verified the HMAC signature. It matched. The response was HTTP 200 with admin data. Cryptographically valid — semantically fraudulent.

0.16 seconds is the stat that matters. That's how long it took to recover a secret that gives an attacker unlimited token-forgery capability — any identity, any role, for as long as the application uses that key.

What Was Already in the Token (JWT-04)

Before running any attack, SecurityClaw decoded Alice's token. JWTs are Base64-encoded, not encrypted. The payload is readable by anyone who holds the token — including every proxy, log aggregator, CDN, and browser developer tools session the token passes through.

{
  "sub": "alice",
  "role": "user",
  "email": "alice@acmecorp.com",
  "password_hash": "a7f5c3e9b4d1f08c29a7f5c3e9b4d1f0",
  "internal_id": "USR-9820"
}

There it is. password_hash in plain sight. An MD5 hash of Alice's password, embedded in a token that Alice's browser stores in localStorage, that every JavaScript file on the page can read, that every HTTP log records. Pass it to SecurityClaw's hashcat campaign (D14) — which cracked 5/6 hashes in under a second — and Alice's actual password is moments away.

JWT is signed, not encrypted. The signature proves the token was issued by the server. It does not hide the contents from anyone. Anything in the payload is readable by anyone who touches the token.

The Expiry Problem (JWT-03)

Alice's token has no exp claim. It was issued today. It will be valid in six months. In two years. Forever.

An attacker who steals this token — via XSS, a compromised device, a log file, a network tap on an unencrypted connection — has permanent access to Alice's account. There is no time-based expiry forcing the token to become invalid. No re-authentication required. The window to abuse a stolen token is unlimited.

Combined with JWT-02 and JWT-01, the missing expiry means forged tokens also never expire. Once an attacker has either bypass technique working, they have permanent admin access until the key is rotated or the algorithm check is enforced.

The Honest Miss

SecurityClaw's jwt-tool also tests for RS256→HS256 algorithm confusion — a separate attack class where an application that supports both RSA and HMAC algorithms can be tricked into verifying a token signed with the server's public RSA key treated as an HMAC secret.

This attack was not applicable here. The AcmeCorp API Gateway uses HS256 only — no RSA key pair is involved. The attack requires a server that exposes an RSA public key (e.g., via a JWKS endpoint) and accepts both RS256 and HS256 tokens. That attack surface doesn't exist in a pure HMAC implementation.

The miss is documented for two reasons. First, transparency: we tested it and it didn't apply. Second, to be useful: if you're assessing an API that uses RS256 or exposes a JWKS endpoint, algorithm confusion is the first thing to test. It's a different vulnerability class on a different target configuration.

The Attack Chain Context

D19 fits into the SecurityClaw attack chain at the authentication escalation stage:

  1. D16 (ffuf) — discovers /api/login, /api/admin/, and the JWKS endpoint in 2.0 seconds.
  2. D15 (Hydra) — brute-forces Alice's credentials. Gets a valid JWT.
  3. D19 (jwt-tool) — forges admin token via alg:none bypass (or cracks the signing secret). Escalates from role:user to role:admin without another login.
  4. D14 (hashcat) — cracks the MD5 password hash found in the JWT payload. Recovers Alice's actual password for use across other services.

The D19 finding that the password hash lives in the JWT payload feeds directly into the D14 campaign. The attack chain is designed to exploit exactly this kind of cascading vulnerability — where one finding creates the input for the next.

The Remediation Table

VulnerabilityFix
JWT-02: alg:none accepted Explicitly whitelist HS256 only. Reject any other algorithm — including none — unconditionally, before signature verification.
JWT-01: Weak signing secret Generate with openssl rand -hex 32. Store in a secrets manager (not in code or config files). Rotate if exposed. Never use dictionary words, names, or service names as secrets.
JWT-03: No expiration Set exp claim on every issued token. 1 hour for general API access, 15 minutes for sensitive operations. Implement refresh token rotation.
JWT-04: Sensitive data in payload JWT is signed, not encrypted — treat payload as public. Never put passwords, hashes, PII, or internal system data in JWT payload. Use opaque references (user IDs) that have no value outside the application.

For deeper coverage of JWT attack patterns, authentication bypass techniques, and API security testing methodology, Hacking APIs by Corey Ball is the definitive reference. Chapter 7 covers JWT attacks in full, including algorithm confusion, key injection, and kid (key ID) header injection — attacks beyond what this demo covers. The Hacker Playbook 3 covers authentication bypass within broader penetration test engagement methodology.

SecurityClaw Scorecard: D19

MetricValue
Tooljwt-tool
TargetAcmeCorp API Gateway (Flask, HS256)
Vulnerabilities found4 / 4
CRITICAL findings2 (alg:none bypass; weak secret cracked)
MEDIUM findings2 (no expiry; password hash in payload)
Admin access achieved via alg:none✅ Under 200ms
Signing secret cracked✅ 0.16 seconds (secret123)
RS256→HS256 confusion❌ Not applicable — HS256-only app (honest miss)
TDD tests18 / 18 ✅
Campaign ID33
Campaign resultPASS
Overall scorecard after D1928/31 campaigns = 90.32%

0.16 seconds to crack the signing secret. Under 200ms to full admin access via algorithm bypass. Both CRITICAL findings require a single line of code to fix. The most expensive part of remediating these vulnerabilities is reading the documentation — the implementation is trivial. The cost of not fixing them is the full account database in an attacker's hands before the first alert fires.

Advertisement