JWT KID Header Injection
| Severity | High |
|---|---|
| Classifications | CWE-345: Insufficient Verification of Data Authenticity |
| OWASP Category | OWASP API2:2023 Broken Authentication |
The kid (Key ID) JWT header field is intended to tell the server which key to use for signature verification. When this value is passed unsanitized to a database query or a file system lookup, attackers can inject a payload that causes the server to use an attacker-controlled key, effectively allowing them to forge arbitrary tokens.
For more details, you can refer to the jwtop documentation on KID Header Injection.
VulnAPI tests two variants of this attack:
- SQL Injection — injects a SQL payload into
kid(e.g.' UNION SELECT 'secret' ...) so that the database returns a known value as the key. - Path Traversal — sets
kidto a filesystem path such as/dev/nullso the server reads an empty file as the key, which can be matched with an empty HMAC secret.
Example
Section titled “Example”Here is a valid JWT signed with HS256:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5cSQL Injection variant
Section titled “SQL Injection variant”The attacker crafts a token with a kid header that injects into the key-lookup query and re-signs it with the value the query is made to return (secret):
{ "alg": "HS256", "typ": "JWT", "kid": "' UNION SELECT 'secret' FROM tokens WHERE '1'='1"}Path Traversal variant
Section titled “Path Traversal variant”The attacker sets kid to /dev/null and re-signs the token with an empty HMAC secret. If the server reads the signing key from the path named by kid, it receives zero bytes:
{ "alg": "HS256", "typ": "JWT", "kid": "/dev/null"}How to test?
Section titled “How to test?”vulnapi scan curl [url] -H "Authorization: Bearer eyJhbGciOiJIUzI1NiI..." --scans jwt.kid_injectionecho "eyJhbGciOiJIUzI1NiI..." | vulnapi scan openapi [OpenAPI_Path_Or_URL] --scans jwt.kid_injectionvulnapi scan graphql -H "Authorization: Bearer eyJhbGciOiJIUzI1NiI..." --scans jwt.kid_injection [url]VulnAPI supports scanning against various types of other vulnerabilities as well.
What is the impact?
Section titled “What is the impact?”A successful KID injection attack allows an attacker to forge a JWT that the server accepts as legitimate. This can lead to full authentication bypass, privilege escalation, or impersonation of any user in the system.
How to remediate?
Section titled “How to remediate?”- Validate the
kidvalue before using it — reject values containing SQL metacharacters, path separators, or characters outside a safe allowlist (e.g. alphanumeric and hyphens only). - Use parameterised queries when looking up keys by
kidin a database to prevent SQL injection. - Never read key material from user-controlled file paths — store keys in a secure key store and use
kidonly as an opaque identifier mapped server-side to a known key. - Hard-code or allowlist permitted
kidvalues where possible.