Jwt misconfig
bb-huge π€ , Personal bug bounty findings hub and bug bounty orchestration for multiple agents
npx -y skills add ShulkwiSEC/bb-huge --skill jwt-misconfigAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 18 stars18 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Use when testing JWT-based authentication for algorithm confusion, alg:none bypass, weak HMAC secrets, missing expiration, kid parameter injection, and token storage in localStorage. Trigger on: Authorization: Bearer tokens, JWTs in cookies, any base64url encoded header.payload.signature pattern, OAuth2 access tokens, API authentication tokens, SSO tokens, JWKS endpoints. Detects RS256βHS256 confusion, public key as HMAC secret, unverified kid values used in file reads or SQL queries, and JWT cracking with short secrets.
The file declares its own license as Apache-2.0. That is the authorβs claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.
SKILL.md
5.5 KB, as published. Nobody here has run it
JWT Misconfiguration
What Is Broken and Why
JWTs that accept alg: none, trust the algorithm declared in the token header, or use
guessable HMAC secrets allow attackers to forge arbitrary tokens β including admin-level
claims β without knowing any signing key. Algorithm confusion attacks exploit servers
that accept both RS256 (asymmetric) and HS256 (symmetric): the attacker signs with the
public key (which is public) using HS256 and the server verifies it as a valid HMAC.
Key Signals
Authorization: Bearer <base64url>.<base64url>.<base64url>in requests- JWTs stored in cookies (check
httpOnly,Secure,SameSiteflags) - JWKS endpoint at
/.well-known/jwks.jsonor/oauth/certs(exposes public key) algfield in JWT header β watch forHS256,RS256,nonekid(Key ID) field in JWT header β check for path traversal or SQLi- Short or dictionary-based HMAC secret (crack with hashcat)
Methodology
- Decode the JWT header and payload (
base64urldecode each part). - Note the
algvalue; attempt to change it tononeand remove signature. - If
algisRS256, fetch the public key from JWKS endpoint; re-sign with HS256 using the public key as the HMAC secret. - If
algisHS256, attempt to crack the secret withhashcatorjwt_tool. - Check
kidvalue β test for path traversal (../../dev/null), SQLi, or SSRF. - Modify
expclaim to far-future timestamp; attempt to use expired tokens. - Escalate claims: change
role,admin,sub,userIdin payload after forging.
Payloads & Tools
# jwt_tool β Swiss army knife for JWT attacks
pip install jwt_tool
jwt_tool TOKEN -X a # alg:none attack
jwt_tool TOKEN -X s # algorithm confusion (RS256βHS256)
jwt_tool TOKEN -C -d wordlist.txt # crack HMAC secret
# hashcat JWT cracking
hashcat -a 0 -m 16500 TOKEN wordlist.txt
# Manual alg:none
# 1. Decode header: {"alg":"RS256","typ":"JWT"}
# 2. Change to: {"alg":"none","typ":"JWT"}
# 3. Re-encode and append empty signature: header.payload.
# (trailing dot is required)
# kid SQLi
{"kid": "' UNION SELECT 'attacker_secret' --", "alg":"HS256"}
# Sign token with 'attacker_secret'
# kid path traversal (sign with empty string)
{"kid": "../../dev/null", "alg":"HS256"}
# /dev/null reads as empty β sign with empty string ""
Bypass Techniques
| Attack | Technique |
|---|---|
alg: none | Change header alg to none, drop signature, keep trailing dot |
| Algorithm confusion | Fetch RS256 public key; use it as HS256 HMAC secret |
| Weak secret | Crack short/dictionary HMAC with hashcat -m 16500 |
kid path traversal | Point kid to /dev/null or known empty file; sign with "" |
kid SQLi | Inject SQL into kid to return attacker-controlled key from DB |
Missing exp | If no expiry check, reuse old tokens indefinitely |
jku/x5u injection | Point to attacker-hosted JWKS to supply own public key |
| Embedded JWK | Inject jwk into header containing attacker's own public key |
Exploitation Scenarios
Algorithm confusion to admin:
Setup β API uses RS256; JWKS endpoint public at /.well-known/jwks.json.
Trigger β Fetch public key β re-sign token with HS256 using public key as secret β set
"role":"admin" in payload.
Impact β Full admin access without any private key.
alg:none on misconfigured library:
Setup β Old version of JWT library doesn't reject alg: none.
Trigger β Set alg: none, modify sub to another user's ID, remove signature.
Impact β Arbitrary account takeover.
kid path traversal to RCE:
Setup β kid is used to load key from filesystem without sanitization.
Trigger β kid: "../../proc/self/fd/0" with socket input; or ../../tmp/evil.
Impact β Attacker controls signing key; full token forgery.
False Positives
alg: nonerejected with 401 β library properly validates algorithm.- RS256 server that only accepts RS256 (not HS256) β algorithm confusion not applicable.
- JWKS endpoint present but server uses pinned key in code β
jku/x5uinjection blocked.
Fix Patterns
// Always whitelist algorithm β never derive from token header
jwt.verify(token, secret, { algorithms: ['HS256'] });
// For RS256: pin the public key in code, don't trust jku/jwk headers
jwt.verify(token, publicKeyPem, { algorithms: ['RS256'] });
// Always validate exp
const decoded = jwt.verify(token, secret, {
algorithms: ['HS256'],
ignoreExpiration: false // default false β make it explicit
});
Related Skills
JWT attacks are a class of [[auth-bypass]] specific to token-based systems. kid SQLi
chains into [[sql-injection]]; kid path traversal chains into [[path-traversal]].
Weak session management after JWT compromise connects to [[cookie-attacks]] and
[[session-fixation]].