According to the JWS specification, only the alg header parameter is mandatory. In practice, however, JWT headers (also known as JOSE headers) often contain several other parameters. The following ones are of particular interest to attackers.
jwk (JSON Web Key) - Provides an embedded JSON object representing the key.
jku (JSON Web Key Set URL) - Provides a URL from which servers can fetch a set of keys containing the correct key.
kid (Key ID) - Provides an ID that servers can use to identify the correct key in cases where there are multiple keys to choose from. Depending on the format of the key, this may have a matching kid parameter.
Injecting Self-signed JWTs via the Jwk Parameter
JWK
A JWK (JSON Web Key) is a standardized format for representing keys as a JSON object.
Ideally, servers should only use a limited whitelist of public keys to verify JWT signatures. However, misconfigured servers sometimes use any key thatās embedded in theĀ jwkĀ parameter.
You can exploit this behavior by signing a modified JWT using your own RSA private key, then embedding the matching public key in theĀ jwkĀ header.
Lab: JWT Authentication Bypass via Jwk Header Injection
First, generate a RSA key pair with JWT Editor extension of Burp Suite:
JWK Sets like this are sometimes exposed publicly via a standard endpoint, such asĀ /.well-known/jwks.json.
Quote
More secure websites will only fetch keys from trusted domains, but you can sometimes take advantage of URL parsing discrepancies to bypass this kind of filtering.
Lab: JWT Authentication Bypass via Jku Header Injection
This lab provides us an exploit server.
Generate a RSA key and it as JWK into clipboard.
We build a JWK Set that has the generated key like this:
Sign it with the generated RSA key (key with ID 18c5ae28-d29f-4f3b-bbde-481d63ee4ecd) and send the request.
Injecting Self-signed JWTs via the Kid Parameter
Quote
The JWS specification doesnāt define a concrete structure for this ID - itās just an arbitrary string of the developerās choosing. For example, they might use theĀ kidĀ parameter to point to a particular entry in a database, or even the name of a file.
This is especially dangerous if the server also supports JWTs signed using a symmetric algorithm. In this case, an attacker could potentially point the kid parameter to a predictable, static file, then sign the JWT using a secret that matches the contents of this file.
You could theoretically do this with any file, but one of the simplest methods is to use /dev/null, which is present on most Linux systems. As this is an empty file, reading it returns an empty string. Therefore, signing the token with a empty string will result in a valid signature.
Quote
If the server stores its verification keys in a database, the kid header parameter is also a potential vector for SQL injection attacks.
Lab: JWT Authentication Bypass via Kid Header Path Traversal
Sign it by using jwt.io with empty string as secret key.
Send the request and we get the error message so try again with the following header:
{ "kid": "../../../dev/null", "alg": "HS256"}
Other Interesting JWT Header Parameters
cty (Content Type): change the content type to text/xml or application/x-java-serialized-object, which can potentially enable new vectors for XXE and deserialization attacks.
x5c (X.509 Certificate): Due to the complexity of the X.509 format and its extensions, parsing these certificates can also introduce vulnerabilities. Examples: CVE-2017-2800 and CVE-2018-2633