Safeguard
Vulnerability Analysis•

CVE-2026-102275: Medium OKP Key Mismatch in PyJWT 2.1.0 to 2.14.0

CVE-2026-102275 lets PyJWT accept OKP private keys whose x and d do not match, which can weaken DPoP checks. Upgrade to 2.15.0; reject proof keys.

Safeguard Security Team
3 min read

CVE-2026-102275 is a Medium (CVSS 6.5) key identity flaw in PyJWT from 2.1.0 before 2.15.0. It accepts OKP private keys whose public part does not match the private part. In some DPoP integrations this can let a stolen token be used. Upgrade to 2.15.0.

What's affected

The weaknesses are CWE-345 (insufficient verification of data authenticity) and CWE-348 (use of less trusted source). The record says PyJWT from 2.1.0 until 2.15.0 is affected, and the GitHub advisory agrees: 2.1.0 through 2.14.0 affected, 2.15.0 patched.

When an OKP private key in JWK form is imported, PyJWT builds the Ed25519 or Ed448 private key from the private value d. It does not check that the public key derived from d matches the x value in the same JWK. The key can therefore claim one public identity while cryptographic operations use a different key.

The practical risk depends on the integration. The advisory says that in affected DPoP deployments, this can allow a stolen sender constrained access token to be used without possession of the legitimate holder's private key. The record adds a condition: the integration must also accept private key parameters from a proof header without rejecting them. Plain JWT verification with public keys is not what the advisory describes.

The vector in the record is network, high complexity, no privileges, with high impact on integrity and low on confidentiality.

How to check if you're exposed

Check the version.

pip show pyjwt

Versions 2.1.0 through 2.14.0 are in scope. Then check whether you use OKP keys, that is Ed25519 or Ed448 in JWK form, and whether you implement DPoP or any proof of possession scheme that reads a public key from a header in the proof.

If your server reads the key from the proof header, check that it rejects any JWK that contains private parameters such as d. That check is a good control whether or not the library is patched.

The free in-browser dependency scan at gold.safeguard.sh/scan can match a lockfile or manifest against known CVEs without installing anything. The Gold directory page for each CVE lists affected packages and fixes as they are published.

What to do now

  1. Upgrade PyJWT to 2.15.0 or later.
  2. In DPoP or proof of possession code, reject any proof header JWK that contains private key parameters.
  3. Compare the public key in a proof against the one bound to the token using a thumbprint rather than trusting the key as presented.
  4. Review where your services import JWKs, and whether any source is untrusted.
  5. Rebuild and redeploy services that bundle PyJWT.

Why it matters

Sender constrained tokens work only if the holder proves control of a specific key. If a library lets the declared key and the used key drift apart, the proof no longer means what the server thinks it means.

The flaw needs a specific integration mistake alongside it, which is why the advisory frames it as conditional and the record scores it Medium. The record does not mark the CVE as known exploited. The sensible lesson is to treat any key presented in a request as untrusted input.

Quick check

Does this affect ordinary JWT verification?

The advisory describes OKP private JWK import and DPoP style integrations. Ordinary verification with a public key you configured is not what it describes.

What is the fixed version?

2.15.0, per the record and the GitHub advisory.

Sources

Last reviewed: 18 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.