Skip to content
JWTForge

JWT kid Header Injection (path traversal, SQLi, command injection)

The kid (key ID) header tells the server which key to use to verify a token. If the server uses that attacker-controlled value to look up a key — by file path, database query, or shell command — without sanitizing it, kid becomes an injection point.

Updated 2026-06-12

How it works

kid is a hint in the JWT header that selects a verification key. Servers resolve it in different ways, and each is an injection surface when the value is trusted blindly:

  • Path traversal. If kid is used as a file path, a value like ../../../../dev/null points the key to an empty file. The attacker then signs the token with an empty key, which the server reproduces — a working forgery. (HMAC zero-pads an empty key, so an empty-key MAC is well-defined.)
  • SQL injection. If kid feeds a query like SELECT key FROM keys WHERE id = '{kid}', a payload can make the query return an attacker-known value used as the signing key.
  • Command injection. If kid is passed to a shell, classic OS-command-injection payloads apply.

Why it matters

Depending on the sink, kid injection ranges from full authentication bypass (the /dev/null empty-key trick) to data exfiltration or remote code execution on the auth server.

How to test for it

Use the Attack tab's kid-injection generator. It builds the /dev/null variant signed with an empty key (a real forgery if the server resolves kid to a file), plus SQLi/command-injection payloads in the kid value. Send them to a target you are authorized to test and watch for accepted tokens, SQL errors, or timing differences.

How to fix it

  • Treat kid as untrusted input: validate it against an allow-list of known key IDs, never interpolate it into a path, query, or command.
  • Use parameterized queries and avoid filesystem/shell lookups by kid.
  • Reject tokens whose kid is unknown rather than falling back to a default.

Related: algorithm confusion and the alg:none attack.