CVE-2026-102271 Overview
CVE-2026-102271 affects PyJWT, a Python implementation of JSON Web Token (JWT) standards. Versions from 2.4.0 up to 2.14.0 contain a flaw in HMACAlgorithm.prepare_key where the asymmetric-key guard relies on textual PEM markers absent from Distinguished Encoding Rules (DER) encoded keys. When an application mixes HMAC and asymmetric algorithms and supplies a DER public key as the shared verification key, PyJWT uses those public DER bytes as the HMAC secret. An attacker who knows the public key can then forge authenticated HMAC tokens. The issue is fixed in PyJWT 2.14.0 and is tracked as [CWE-347: Improper Verification of Cryptographic Signature].
Critical Impact
Attackers with access to a public key can forge signed JWTs, bypassing authentication in applications that mix HMAC and asymmetric verification.
Affected Products
- PyJWT versions 2.4.0 through 2.13.x
- Python applications that mix HMAC and asymmetric JWT algorithms
- Services accepting DER-encoded public keys as verification material
Discovery Timeline
- 2026-09-28 - CVE-2026-102271 published to NVD
- 2026-09-30 - Last updated in NVD database
Technical Details for CVE-2026-102271
Vulnerability Analysis
PyJWT's HMACAlgorithm.prepare_key function is responsible for validating and normalizing the key material used for HMAC operations. Historically, the guard designed to reject asymmetric keys checked for textual PEM markers such as -----BEGIN PUBLIC KEY-----. DER-encoded keys carry no such ASCII markers because they are binary structures. As a result, a DER public key passes the guard and is treated as raw HMAC secret bytes.
This becomes exploitable in applications that permit algorithm confusion between asymmetric algorithms (for example, RS256 or ES256) and symmetric ones (HS256). If the verifier passes the intended public key to jwt.decode while allowing HS256, PyJWT computes an HMAC over the token using the public key bytes. Because public keys are, by definition, not secret, any attacker holding the key can produce a valid signature.
Root Cause
The root cause is an incomplete input classification check. The prepare-key logic distinguished PEM-encoded asymmetric keys but omitted DER detection, allowing binary-encoded public keys through as HMAC secrets [CWE-347].
Attack Vector
Exploitation requires an application to accept a JWT algorithm list that includes an HMAC variant while configuring a DER public key as the verification key. The attacker crafts a JWT with the alg header set to HS256, signs the token using the known public DER bytes, and submits it. The verifier reproduces the same HMAC and accepts the forged token as authentic.
# Patch excerpt from jwt/algorithms.py — reject DER public keys as HMAC secrets
try:
from cryptography import x509
from cryptography.exceptions import InvalidSignature, UnsupportedAlgorithm
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
Source: GitHub Commit 2798504. The fix imports cryptography.x509 and related primitives so prepare_key can parse DER blobs and reject any key that decodes as an asymmetric public key.
Detection Methods for CVE-2026-102271
Indicators of Compromise
- JWTs presented to the application with alg: HS256 when the service documentation specifies RS256, ES256, or another asymmetric algorithm.
- Authentication events succeeding for tokens whose signature was computed over the deployed public key bytes.
- Sudden appearance of privileged sessions issued to accounts that did not perform an interactive login.
Detection Strategies
- Inventory Python services and CI images for PyJWT versions between 2.4.0 and 2.13.x using pip show pyjwt or SBOM analysis.
- Audit call sites of jwt.decode to confirm the algorithms parameter is restricted to a single family and never contains both HMAC and asymmetric variants simultaneously.
- Log and alert on decoded JWT headers where the alg value diverges from the expected algorithm for that endpoint.
Monitoring Recommendations
- Forward authentication and application logs to a central analytics platform and baseline the expected alg header per service.
- Instrument JWT verification code paths to record the key type and algorithm actually used during verification.
- Track outbound distribution of public keys and correlate with anomalous authentication activity that follows their publication.
How to Mitigate CVE-2026-102271
Immediate Actions Required
- Upgrade PyJWT to version 2.14.0 or later across all Python services, containers, and build pipelines.
- Explicitly restrict the algorithms argument on every jwt.decode call to the exact algorithm the application expects.
- Rotate any signing keys or session material that may have been issued through a mixed-algorithm verification path.
Patch Information
The fix ships in PyJWT 2.14.0 via commit 2798504fa2663364573cf2d1043d8d7fef389499. Additional context is available in GHSA-p4g4-x82p-q773. The patched prepare_key uses the cryptography library to parse DER content and reject asymmetric public keys before they reach the HMAC path.
Workarounds
- If upgrading immediately is not possible, hardcode algorithms=["RS256"] (or the specific asymmetric algorithm in use) and never include HMAC variants in the list.
- Wrap jwt.decode in an application-level check that inspects the supplied key material and rejects any value that parses as a public key when HMAC is expected.
- Serve only PEM-encoded keys to verification code paths that predate the fix, since PEM markers still trigger the original guard.
# Upgrade PyJWT to the fixed release
pip install --upgrade "pyjwt>=2.14.0"
# Verify the installed version
python -c "import jwt; print(jwt.__version__)"
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.