CVE-2026-102270 Overview
CVE-2026-102270 is a regular expression denial of service (ReDoS) vulnerability in PyJWT, a widely used Python implementation of the JSON Web Token (JWT) standards. Versions prior to 2.14.0 contain a lazy PEM regular expression in the is_pem_format helper that backtracks extensively when parsing certificate-like input. An attacker who supplies a payload containing repeated BEGIN markers without a matching END marker can trigger unbounded backtracking. The result is intensive CPU consumption in the process performing the PEM detection. The issue is tracked under [CWE-1333: Inefficient Regular Expression Complexity] and is fixed in PyJWT 2.14.0.
Critical Impact
An authenticated attacker able to submit crafted key material to a PyJWT consumer can exhaust CPU resources and degrade or halt availability of the affected service.
Affected Products
- PyJWT versions prior to 2.14.0
- Python applications that pass attacker-influenced key material to jwt.utils.is_pem_format
- Downstream libraries and services bundling vulnerable PyJWT releases
Discovery Timeline
- 2026-09-28 - CVE-2026-102270 published to NVD
- 2026-09-30 - Last updated in NVD database
Technical Details for CVE-2026-102270
Vulnerability Analysis
The defect resides in jwt/utils.py, where is_pem_format uses a regular expression to determine whether a byte string looks like a PEM-encoded key. The original pattern matched a BEGIN marker, then lazily consumed content up to a corresponding END marker of the same label. When input contains many BEGIN markers but no matching END, the regex engine repeatedly retries alternative match positions before failing. This is a textbook algorithmic complexity attack against a backtracking regex engine. Because is_pem_format runs during key parsing, any code path that feeds attacker-controlled key data into PyJWT can be forced into a long CPU-bound loop, blocking the thread and starving other requests.
Root Cause
The root cause is an unbounded lazy quantifier (.+?) combined with a required tail (----[- ]END \1[- ]----) inside a re.DOTALL pattern. When the tail cannot be satisfied, the engine backtracks across every possible split of the lazy region for every BEGIN prefix, producing worst-case behavior consistent with [CWE-1333].
Attack Vector
Exploitation requires the attacker to control the byte string passed to is_pem_format. In practice this occurs when applications accept public keys, certificates, or JWKS material from users, tenants, or federated identity providers and then attempt to load them through PyJWT. Submitting a payload of repeated -----BEGIN CERTIFICATE----- markers without a closing -----END----- triggers the pathological match.
# Patch from PyJWT 2.14.0 — jwt/utils.py
# Replaces the backtracking regex with a non-consuming lookahead that
# enumerates BEGIN/END markers and validates pairing in linear time.
-_PEM_RE = re.compile(
- b"----[- ]BEGIN ("
- + b"|".join(_PEMS)
- + b""")[- ]----\r?
-.+?\r?
-----[- ]END \\1[- ]----\r?\n?""",
- re.DOTALL,
+_PEM_MARKER_RE = re.compile(
+ b"(?=(----[- ](BEGIN|END) (" + b"|".join(_PEMS) + b")[- ]----))"
)
def is_pem_format(key: bytes) -> bool:
- return bool(_PEM_RE.search(key))
+ begin_markers: dict[bytes, int] = {}
+ for marker in _PEM_MARKER_RE.finditer(key):
+ marker_type, label = marker.group(2), marker.group(3)
+ if marker_type == b"BEGIN":
+ begin_markers[label] = marker.start(1) + len(marker.group(1))
+ elif label in begin_markers and begin_markers[label] < marker.start(1):
+ return True
+ return False
Source: PyJWT commit 8b4e233
Detection Methods for CVE-2026-102270
Indicators of Compromise
- Sustained single-thread CPU saturation in Python processes that call jwt.utils.is_pem_format or jwt.algorithms.*.from_jwk.
- Request payloads or JWKS documents containing many repeated -----BEGIN markers without a matching -----END line.
- Application timeouts, worker restarts, or 5xx spikes correlated with authentication or token-verification endpoints.
Detection Strategies
- Inventory Python dependencies and flag any PyJWT version below 2.14.0 using pip list, SBOM tooling, or software composition analysis.
- Add application-layer logging around PEM/JWK ingestion paths to record input size, marker counts, and parse duration.
- Alert on anomalous CPU time per request on token verification endpoints, especially where request bodies contain certificate-like material.
Monitoring Recommendations
- Track process CPU utilization and event loop lag for services that handle JWTs from untrusted sources.
- Monitor web application firewall (WAF) logs for POST bodies containing repeated BEGIN markers.
- Correlate authentication error rates with upstream identity provider changes that may introduce new key material.
How to Mitigate CVE-2026-102270
Immediate Actions Required
- Upgrade PyJWT to 2.14.0 or later in all Python environments, including containers, serverless functions, and CI runners.
- Rebuild and redeploy application images to ensure transitive PyJWT dependencies are refreshed.
- Enforce strict size limits on any user-supplied key or certificate material before it reaches PyJWT.
Patch Information
The fix is available in the PyJWT 2.14.0 release. Technical details are documented in GitHub Security Advisory GHSA-jwrc-g2q2-pq5p and the upstream commit. The patch replaces the backtracking regex with a lookahead-based marker scan and validates BEGIN/END pairing in linear time.
Workarounds
- Reject inputs to key-parsing routines that exceed a conservative byte length (for example, 16 KB) before invoking PyJWT.
- Wrap calls into PyJWT key loaders with a CPU or wall-clock timeout using a worker process or signal.alarm on POSIX systems.
- Filter incoming payloads at the WAF or API gateway to drop requests containing more than one -----BEGIN marker in unexpected fields.
# Upgrade PyJWT to the fixed release
pip install --upgrade "PyJWT>=2.14.0"
# Verify the installed version
python -c "import jwt; print(jwt.__version__)"
# Audit environments for vulnerable versions
pip list --format=freeze | grep -i '^PyJWT=='
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.