Skip to content

JWTs can be "successfully" encoded and decoded even when algorithm does not match the EC curve type #1023

Open
@DavidBuchanan314

Description

@DavidBuchanan314

You can generate a SECP256K1 keypair and then tell pyjwt to sign a message using algorithm "ES256".

Expected Result

An exception should be raised, because the SECP256K1 curve is not compatible with the ES256 algorithm (it wants ES256K).

Actual Result

An invalid JWT is encoded (signature will not verify against declared algorithm).

Subsequently, the invalid JWT can be decoded "successfully" without error.

This is arguably a security issue, but it only arises if you use the API "wrong". Nonetheless, I think the API should try to guard against such incorrect uses.

Reproduction Steps

from cryptography.hazmat.primitives.asymmetric import ec
import jwt

#KEY_TYPE = ec.SECP256R1()
KEY_TYPE = ec.SECP256K1()

privkey = ec.generate_private_key(KEY_TYPE)

my_jwt = jwt.encode(
	{ "hello": "world" },
	privkey,
	algorithm="ES256", # nistp256 aka ec.SECP256R1()
)

print(my_jwt) # I think this should raise an exception!

decoded = jwt.decode(my_jwt, key=privkey.public_key(), algorithms=["ES256"])

print(decoded) # This should raise an exception even more so!

System Information

$ python -m jwt.help
{
  "cryptography": {
    "version": "41.0.7"
  },
  "implementation": {
    "name": "CPython",
    "version": "3.12.7"
  },
  "platform": {
    "release": "6.11.0-400.asahi.fc40.aarch64+16k",
    "system": "Linux"
  },
  "pyjwt": {
    "version": "2.10.0"
  }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions