Attack ChainAIDerived
Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain
-
AccessSteal victim sender-constrained DPoP token
-
DeliveryForge OKP JWK: victim x, attacker d
-
ExploitPyJWT imports attacker key, skips x/d check
-
ExecutionSign DPoP proof with attacker key
-
ImpactReplay stolen token impersonating victim
Vulnerability Assessment
| Weakness |
CWE
OWASP Top 10:2025
A08:2025 - Software or Data Integrity Failures
ASVS 5.0
V15 - Secure Coding and Architecture Data authenticity verification
|
| Exploitation Conditions | Exploitation requires three specific conditions, not a default-configuration remote hit: (1) the target application uses PyJWT (2.1.0-2.14.0) OKPAlgorithm.from_jwk / PyJWK.from_dict to import OKP (Ed25519/Ed448) private JWKs; (2) the integration accepts full JWK private-key material - specifically the d parameter - from an attacker-controlled source such as a DPoP proof header, without rejecting private components; and (3) the attacker already possesses a stolen sender-constrained (e.g. DPoP-bound) token whose cnf.jkt thumbprint is computed from x. Limiting factors: the attack fails against integrations that only accept public JWKs in proof headers, that reject JWKs containing d, or that verify key consistency; it also requires prior theft of a valid bound token. Standard signature-verification use of PyJWT with trusted server-side keys is NOT affected. |
| Impact | Signals are mixed and point to a real but conditional threat rather than a mass-exploitation emergency. The vendor CVSS 3.1 vector (AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H, 8.2 High) implies trivial unauthenticated network exploitation, but the description and GHSA advisory make clear this only matters when an integration accepts private-key JWK parameters (d) from an attacker-controlled DPoP proof header AND the attacker already possesses a stolen sender-constrained token - so the practical complexity is higher than AC:L suggests. SSVC agrees it is not a drop-in mass exploit: Exploitation=poc, Automatable=no, Technical Impact=partial. EPSS is very low (0.14%, 3rd percentile) and the CVE is NOT in CISA KEV, consistent with no observed widespread exploitation. A working PoC exists (publicly available exploit code), confirming the key-confusion is real and reproducible, but PoC availability is not active exploitation. Net: this is a genuine authentication/identity-confusion flaw worth prioritizing specifically for services using PyJWT for DPoP or other OKP private-JWK import flows, but it is not an indiscriminate internet-wide risk. Note the conflict to verify: CVSS AC:L understates the real-world precondition (stolen token + permissive integration), so raw 8.2 overstates realistic risk for most deployments. |
| Exploit ScenarioDerived | An attacker who has intercepted a victim's sender-constrained (DPoP) access token crafts an OKP JWK containing the victim's legitimate public key x together with the attacker's own private key d, and submits it in a DPoP proof header. Because PyJWT's OKPAlgorithm.from_jwk never checks that x corresponds to d, it builds the key from the attacker's d while the RFC 7638 thumbprint still matches the victim binding, so the attacker signs a valid proof and replays the stolen token without ever holding the victim's private key. A public PoC demonstrates this end-to-end (stolen_sender_constrained_token_accepted: true). |
Get an e-mail when this CVE is exploited, patched or re-scored. Free account.
Alert meAnalysisAIv2 – Oct 06, 2026
Improper validation in PyJWT 2.1.0 through 2.14.0 allows an attacker who already holds a stolen sender-constrained (DPoP-bound) access token to replay it without possessing the legitimate holder's private key, because OKPAlgorithm.from_jwk imports an Ed25519/Ed448 private JWK from the d parameter without checking that the public key derived from d matches the declared x. An attacker-supplied JWK that pairs the victim's x with the attacker's own d therefore satisfies RFC 7638 thumbprint binding (cnf.jkt) while all signing operations use the attacker's key. Publicly available exploit code exists (a public gist reproducer), but EPSS is only 0.14% (3rd percentile) and there is no KEV listing - this is a conditional, integration-dependent flaw rather than a default-configuration remote compromise, and standard signature-verification use of PyJWT with trusted server-side keys is not affected.
Earlier versions of this analysis (1)
PyJWT 2.1.0 through 2.14.x fails to verify that the public component embedded in an OKP (Ed25519/Ed448) private JWK actually corresponds to the supplied private key material, so OKPAlgorithm.from_jwk returns a key object whose declared identity (x) can diverge from the key used for cryptographic operations (d). In integrations that parse private-key JWK parameters out of an attacker-controllable proof header instead of rejecting them and that rely on sender-constrained / proof-of-possession token binding, an unauthenticated remote attacker who already holds a stolen but otherwise valid token can present proof material signed with their own key and have it accepted without the legitimate private key, giving an integrity-only impact rated medium (CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:H/A:N). The issue is not listed in CISA KEV and no public exploit code has been identified at time of analysis; the root cause is remediated in PyJWT 2.15.0.
RemediationAI
Upgrade PyJWT to 2.15.0 (pip install -U PyJWT) - vendor-released patch: 2.15.0 - which is the fix commit https://github.com/jpadilla/pyjwt/commit/3cd9ceec33ced359decbad75b413ad668ae6332c; that change derives the public key from d and raises InvalidKeyError("Public key does not match private key") when it differs from x. Where upgrading is not immediately possible, apply these specific compensating controls in the integration layer, each with trade-offs: (1) reject any DPoP proof or other attacker-supplied JWK that contains a "d" (or any private-key parameter) before handing it to PyJWK.from_dict, and accept only public JWKs for proof verification - this defeats the attack entirely but will break any (non-standard) workflow that legitimately expects private JWK material from a request header; (2) wrap OKPAlgorithm.from_jwk/PyJWK.from_dict and independently reconstruct the public key from d, aborting if it does not equal x - low overhead, but a per-call check that must be applied everywhere the library is used; (3) treat DPoP/thumbprint binding as one factor rather than the sole control for sender-constrained tokens (short token lifetimes, holder-of-key re-binding on sensitive operations, anomaly detection on key-substitution patterns) - reduces blast radius but does not eliminate acceptance of stolen tokens. Note that this is not a memory-safety or RCE issue and that standard JWS/JWT signature verification with server-trusted keys needs no change; remediation effort should be prioritised on DPoP/OAuth resource servers and any endpoint that parses client-supplied JWKs.
Affected VersionsENISA
Affected Packages
Source: OSV (Open Source Vulnerabilities)
Affects your stack
Affects 1 package in pypi
Checking this CVE against your own stacks and servers is part of the Basic plan and up.
Technical ContextAI · show details
PyJWT is a Python implementation of JWT/JWK/JWS standards, and CVE-2026-102275 is a CWE-345 (Insufficient Verification of Data Authenticity) defect in the OKP key-import path of jwt/algorithms.py. Octet Key Pair (OKP) JWKs for Ed25519/Ed448 carry a public key in x and, optionally, a private seed in d; correct import must derive the public key from d and reject the JWK if it does not equal x. PyJWT instead parsed x only to confirm its presence and then constructed Ed25519PrivateKey/Ed448PrivateKey directly from d, so a JWK declaring one identity (x) could perform cryptographic operations under a different identity (d). The impact materialises in sender-constrained token schemes such as DPoP, where an access token binds to a key via the RFC 7638 JWK thumbprint in the cnf.jkt claim: the thumbprint is computed from x, so an attacker who supplies the legitimate x plus their own d passes the binding check while signing DPoP proofs with their own key. The defect was present since OKP private-JWK import was introduced (Ed25519 from PyJWT 2.1.0, Ed448 from 2.2.0) and persisted through 2.14.0; the affected package is tracked as CPE cpe:2.3:a:jpadilla:pyjwt:*:*:*:*:*:*:*:* and as EUVD-2026-88547 (pyjwt 2.1.0, < 2.15.0).
Know when Pyjwt gets its next vulnerability
- Watch products and get an email when something new is published
- Check this CVE against your own stack and servers
- Exploit and PoC references, threat intelligence from 22 sources
No credit card · 7-day full trial
Severity by source
AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:N
Attacker is unauthenticated (no legitimate private key) so PR:N, but needs a permissive DPoP integration plus a previously stolen token, so AC:H; impact is primarily impersonation/integrity (I:H) with limited confidentiality (C:L).
AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:H/A:N
Primary rating from Vendor (GitHub_M).
CVSS VectorNVD
Lifecycle Timeline
4DescriptionNVD
PyJWT is a Python implementation of JSON Web Token standards. From 2.1.0 until 2.15.0, PyJWT OKPAlgorithm.from_jwk in jwt/algorithms.py is affected because private-JWK import path does not compare the public key derived from d with x. This occurs when an OKP private JWK supplies non-corresponding x and d components. As a result, identity derived from x can differ from operations performed with d. Consequently, if an integration also accepts private key parameters from a proof header without rejecting them, an attacker may use a stolen sender-constrained token without the legitimate private key. This issue is fixed in version 2.15.0.
Blast Radius
ecosystem impact- 96 pypi packages depend on pyjwt (73 direct, 25 indirect)
Ecosystem-wide dependent count for version 2.1.0.
Technical POC Analysis
CWE-345 (Insufficient Verification of Data Authenticity); the advisory also assigns CWE-348 (Use of Less Trusted Source).
Full technical POC analysis - root cause, step-by-step exploitation and patch breakdown - is part of the Pro and Business plans.
Latest POC
1 public PoC link from github
Sign in to open the public PoC links collected for this CVE.
Executive ViewAI
A flaw in PyJWT versions 2.1.0 through 2.14.0 can allow an attacker who already holds a stolen DPoP-bound access token to replay it without the legitimate holder's private key, weakening sender-constrained token protections for applications that use this library. Publicly available exploit code exists, but exploitation depends on a stolen token and specific integration patterns rather than default remote compromise, so exposure is concentrated in services that validate DPoP-bound tokens. Leadership should direct affected teams to patch PyJWT and review token-binding controls because a bypass could enable unauthorized API access using compromised tokens.
Apply vendor patch.
Threat Intelligence Overview
How this decision was reached
The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.
What every action level means
SSVC AssessmentENISA
Priority Score
Forged HS256 JSON Web Tokens can be accepted as authentic by PyJWT (pip package PyJWT) versions 2.13.0 through 2.13.x wh
Denial of service in PyJWT 2.9.0 through 2.13.0: a single malformed RSA JWK embedded in a JWK Set aborts construction of
Unauthenticated denial of service in the PyJWT Python library (versions 2.0.0a1 through 2.14.0) allows a remote attacker
pyjwt is a JSON Web Token implementation in Python. Rated high severity (CVSS 7.5), this vulnerability is remotely explo
Authentication bypass in PyJWT versions prior to 2.13.0 allows remote attackers to forge valid JSON Web Tokens by exploi
Reuse of a caller-supplied options mapping in PyJWT 2.11.0 through 2.13.0 can silently leave registered-claim verificati
Malformed JSON Web Token headers can cause an uncaught RecursionError in PyJWT 2.13.0 through versions before 2.14.0, re
Uncontrolled resource consumption in PyJWT 2.8.0-2.12.1 exposes any service that verifies detached JWS tokens to unauthe
Signature forgery in PyJWT before 2.14.0 allows an attacker who knows a target's asymmetric public key to forge HMAC-aut
JWKS trust-boundary bypass in PyJWT's PyJWKClient allows a configured trusted JWKS endpoint that returns an HTTP 3xx red
Unauthenticated attackers can amplify outbound HTTP traffic from any application that validates JWTs with PyJWT's PyJWKC
In PyJWT 1.5.0 and below the `invalid_strings` check in `HMACAlgorithm.prepare_key` does not account for all PEM encoded
Vendor StatusVendor
SUSE
Severity: Moderate| Product | Status |
|---|---|
| SUSE Linux Enterprise Desktop 15 SP7 | Affected |
| SUSE Linux Enterprise High Performance Computing 12 | Not-Affected |
| SUSE Linux Enterprise Micro 5.5 | Affected |
| SUSE Linux Enterprise Module for Basesystem 15 SP7 | Affected |
| SUSE Linux Enterprise Module for Python 3 15 SP7 | Affected |
| SUSE Linux Enterprise Server 15 SP7 | Affected |
| SUSE Linux Enterprise Server 16.0 | Affected |
| SUSE Linux Enterprise Server 16.1 | Affected |
| SUSE Linux Enterprise Server for SAP Applications 15 SP7 | Affected |
| SUSE Linux Enterprise Server for SAP applications 16.0 | Affected |
| SUSE Linux Enterprise Server for SAP applications 16.1 | Affected |
| SUSE Linux Micro 6.0 | Affected |
| SUSE Linux Micro 6.1 | Affected |
| SUSE Linux Micro 6.2 | Affected |
| openSUSE Leap 16.0 | Affected |
| SUSE Linux Enterprise High Performance Computing 15 SP4-LTSS | Affected |
| SUSE Linux Enterprise High Performance Computing 15 SP5 | Affected |
| SUSE Linux Enterprise High Performance Computing 15 SP5-LTSS | Affected |
| SUSE Linux Enterprise Module for Basesystem 15 SP4 | Affected |
| SUSE Linux Enterprise Module for Basesystem 15 SP5 | Affected |
| SUSE Linux Enterprise Module for Basesystem 15 SP6 | Affected |
| SUSE Linux Enterprise Module for Public Cloud 12 | Not-Affected |
| SUSE Linux Enterprise Module for Public Cloud 15 SP4 | Affected |
| SUSE Linux Enterprise Module for Python 3 15 SP4 | Affected |
| SUSE Linux Enterprise Module for Python 3 15 SP5 | Affected |
| SUSE Linux Enterprise Module for Python 3 15 SP6 | Affected |
| SUSE Linux Enterprise Server 12 SP5 | Not-Affected |
| SUSE Linux Enterprise Server 12 SP5-LTSS | Not-Affected |
| SUSE Linux Enterprise Server 15 SP4 | Affected |
| SUSE Linux Enterprise Server 15 SP4-LTSS | Affected |
| SUSE Linux Enterprise Server 15 SP5 | Affected |
| SUSE Linux Enterprise Server 15 SP5-LTSS | Affected |
| SUSE Linux Enterprise Server 15 SP6 | Affected |
| SUSE Linux Enterprise Server 15 SP6-LTSS | Affected |
| SUSE Linux Enterprise Server LTSS Extended Security 12 SP5 | Not-Affected |
| SUSE Linux Enterprise Server for SAP Applications 12 SP5 | Not-Affected |
| SUSE Linux Enterprise Server for SAP Applications 15 SP4 | Affected |
| SUSE Linux Enterprise Server for SAP Applications 15 SP5 | Affected |
| SUSE Linux Enterprise Server for SAP Applications 15 SP6 | Affected |
| SUSE CaaS Platform 3.0 | Not-Affected |
| SUSE CaaS Platform 4.0 | Not-Affected |
| SUSE Enterprise Storage 6 | Not-Affected |
| SUSE Enterprise Storage 7 | Not-Affected |
| SUSE Enterprise Storage 7.1 | Affected |
| SUSE Linux Enterprise Desktop 15 SP1 | Not-Affected |
| SUSE Linux Enterprise Desktop 15 SP2 | Affected |
| SUSE Linux Enterprise Desktop 15 SP3 | Affected |
| SUSE Linux Enterprise Desktop 15 SP4 | Affected |
| SUSE Linux Enterprise Desktop 15 SP5 | Affected |
| SUSE Linux Enterprise Desktop 15 SP6 | Affected |
| SUSE Linux Enterprise High Performance Computing 15 SP1 | Not-Affected |
| SUSE Linux Enterprise High Performance Computing 15 SP1-ESPOS | Not-Affected |
| SUSE Linux Enterprise High Performance Computing 15 SP1-LTSS | Not-Affected |
| SUSE Linux Enterprise High Performance Computing 15 SP2 | Not-Affected |
| SUSE Linux Enterprise High Performance Computing 15 SP2-ESPOS | Affected |
| SUSE Linux Enterprise High Performance Computing 15 SP2-LTSS | Affected |
| SUSE Linux Enterprise High Performance Computing 15 SP3 | Affected |
| SUSE Linux Enterprise High Performance Computing 15 SP3-ESPOS | Affected |
| SUSE Linux Enterprise High Performance Computing 15 SP3-LTSS | Affected |
| SUSE Linux Enterprise High Performance Computing 15 SP4 | Affected |
| SUSE Linux Enterprise High Performance Computing 15 SP4-ESPOS | Affected |
| SUSE Linux Enterprise High Performance Computing 15 SP5-ESPOS | Affected |
| SUSE Linux Enterprise Module for Basesystem 15 SP1 | Not-Affected |
| SUSE Linux Enterprise Module for Basesystem 15 SP2 | Affected |
| SUSE Linux Enterprise Module for Basesystem 15 SP3 | Affected |
| SUSE Linux Enterprise Module for Package Hub 15 SP1 | Not-Affected |
| SUSE Linux Enterprise Module for Package Hub 15 SP2 | Affected |
| SUSE Linux Enterprise Module for Package Hub 15 SP3 | Affected |
| SUSE Linux Enterprise Module for Package Hub 15 SP5 | Affected |
| SUSE Linux Enterprise Module for Public Cloud 15 SP1 | Not-Affected |
| SUSE Linux Enterprise Module for Public Cloud 15 SP2 | Not-Affected |
| SUSE Linux Enterprise Real Time 15 SP2 | Affected |
| SUSE Linux Enterprise Real Time 15 SP3 | Affected |
| SUSE Linux Enterprise Real Time 15 SP4 | Affected |
| SUSE Linux Enterprise Server 12 | Not-Affected |
| SUSE Linux Enterprise Server 12 SP3 | Not-Affected |
| SUSE Linux Enterprise Server 12 SP4 | Not-Affected |
| SUSE Linux Enterprise Server 15 SP1 | Not-Affected |
| SUSE Linux Enterprise Server 15 SP1-BCL | Not-Affected |
| SUSE Linux Enterprise Server 15 SP1-LTSS | Not-Affected |
| SUSE Linux Enterprise Server 15 SP2 | Not-Affected |
| SUSE Linux Enterprise Server 15 SP2-BCL | Affected |
| SUSE Linux Enterprise Server 15 SP2-LTSS | Affected |
| SUSE Linux Enterprise Server 15 SP3 | Affected |
| SUSE Linux Enterprise Server 15 SP3-BCL | Affected |
| SUSE Linux Enterprise Server 15 SP3-LTSS | Affected |
| SUSE Linux Enterprise Server for SAP Applications 12 | Not-Affected |
| SUSE Linux Enterprise Server for SAP Applications 12 SP3 | Not-Affected |
| SUSE Linux Enterprise Server for SAP Applications 12 SP4 | Not-Affected |
| SUSE Linux Enterprise Server for SAP Applications 15 SP1 | Not-Affected |
| SUSE Linux Enterprise Server for SAP Applications 15 SP2 | Not-Affected |
| SUSE Linux Enterprise Server for SAP Applications 15 SP3 | Affected |
| SUSE Manager Proxy 4.0 | Not-Affected |
| SUSE Manager Proxy 4.1 | Not-Affected |
| SUSE Manager Proxy 4.2 | Affected |
| SUSE Manager Proxy 4.3 | Affected |
| SUSE Manager Proxy LTS 4.3 | Affected |
| SUSE Manager Retail Branch Server 4.0 | Not-Affected |
| SUSE Manager Retail Branch Server 4.1 | Not-Affected |
| SUSE Manager Retail Branch Server 4.2 | Affected |
| SUSE Manager Retail Branch Server 4.3 | Affected |
| SUSE Manager Retail Branch Server LTS 4.3 | Affected |
| SUSE Manager Server 3.2 | Not-Affected |
| SUSE Manager Server 4.0 | Not-Affected |
| SUSE Manager Server 4.1 | Not-Affected |
| SUSE Manager Server 4.2 | Affected |
| SUSE Manager Server 4.3 | Affected |
| SUSE Manager Server LTS 4.3 | Affected |
| SUSE OpenStack Cloud 7 | Not-Affected |
| openSUSE Leap 15.3 | Affected |
| openSUSE Leap 15.4 | Affected |
| openSUSE Leap 15.5 | Affected |
| openSUSE Leap 15.6 | Affected |
EUVD-2026-88547
GHSA-x33g-cr3x-6449
NVD
CVE.org
EPSS
Vulnrichment
Exploit-DB