Generating JWTs (encode()) with alg key set in headers parameter along with a different algorithm parameter value results in malformed JWTs.
Example headers and algorithm values that will result in malformed tokens:
headers = {"typ": "JWT", "alg": "none"}
algorithm = "HS256"
Expected Result
A token signed with let's say HS256 algorithm should always contain alg value set as HS256 in the JWT header.
Actual Result
Tokens can be signed using an algorithm x (eg. HS256) with token header containing a different alg value
Reproduction Steps
import jwt
payload = {"test": "payload"}
headers = {"typ": "JWT", "alg": "none"}
print(jwt.encode(payload = payload, key = "secret", algorithm = "HS256", headers = headers))
Running the snippet above will give: eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJ0ZXN0IjoicGF5bG9hZCJ9.PySJLJ2Js8Z1K0acpZrgOhzHp0sea_N5rrNX1L_FJis. Header + payload in this case is signed using HS256, but the header value in the token is: {"typ":"JWT","alg":"none"}
Similarly,
import jwt
payload = {"test": "payload"}
headers = {"typ": "JWT", "alg": "RS256"}
jwt.encode(payload = payload, key = "secret", algorithm = "HS256", headers = headers)
will result in a token signed using HS256, with the token header being {"typ":"JWT","alg":"RS256"}
System Information
{
"cryptography": {
"version": "3.4.7"
},
"implementation": {
"name": "CPython",
"version": "3.8.8"
},
"platform": {
"release": "5.8.0-53-generic",
"system": "Linux"
},
"pyjwt": {
"version": "2.1.0"
}
}
Root cause
algorithm (L#109 api_jws.py) variable is being used for signing, but header dict (L#93 api_jws.py) is being overwritten with headers method parameter in L#97 api_jws.py leading to alg value being overwritten to the value present in the method parameter headers.
I tried coming up with ways in which this bug could be abused by an adversary, but couldn't find any. And so, I don't think this qualifies as a security issue.
Generating JWTs (
encode()) withalgkey set inheadersparameter along with a differentalgorithmparameter value results in malformed JWTs.Example
headersandalgorithmvalues that will result in malformed tokens:Expected Result
A token signed with let's say HS256 algorithm should always contain
algvalue set as HS256 in the JWT header.Actual Result
Tokens can be signed using an algorithm x (eg. HS256) with token header containing a different
algvalueReproduction Steps
Running the snippet above will give:
eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJ0ZXN0IjoicGF5bG9hZCJ9.PySJLJ2Js8Z1K0acpZrgOhzHp0sea_N5rrNX1L_FJis. Header + payload in this case is signed using HS256, but the header value in the token is:{"typ":"JWT","alg":"none"}Similarly,
will result in a token signed using HS256, with the token header being
{"typ":"JWT","alg":"RS256"}System Information
Root cause
algorithm(L#109 api_jws.py) variable is being used for signing, butheaderdict (L#93 api_jws.py) is being overwritten withheadersmethod parameter in L#97 api_jws.py leading toalgvalue being overwritten to the value present in the method parameterheaders.I tried coming up with ways in which this bug could be abused by an adversary, but couldn't find any. And so, I don't think this qualifies as a security issue.