CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-102265

CVE-2026-102265: Unhandled RecursionError in PyJWT JSON Parser Leading to Denial of Service

Amit Schendel
Amit Schendel
Senior Security Researcher

Sep 30, 2026·5 min read·19 visits

Executive Summary (TL;DR)

PyJWT fails to catch RecursionError during JSON header parsing, allowing remote attackers to crash request-handling threads with malformed JWTs.

An uncontrolled recursion vulnerability exists in PyJWT from version 2.13.0 to 2.14.0. The vulnerability allows remote, unauthenticated attackers to cause a Denial of Service (DoS) via crafted JWT headers that trigger stack exhaustion during JSON decoding.

Vulnerability Overview

PyJWT is a Python implementation of the JSON Web Token (JWT) standards. The library is widely used in web applications to decode and verify security tokens before executing application logic. This role puts PyJWT on the outer perimeter of the application, exposing its parsing code directly to unauthenticated network input.

During the initial decoding stage of a JSON Web Signature (JWS) or JWT, the library parses the base64url-encoded header segment. This parsing must occur before signature verification, as the header contains critical metadata such as the algorithm used to sign the payload. Consequently, any parsing flaw in this phase can be reached without valid credentials or a verified cryptographic signature.

The vulnerability is classified under CWE-674 (Uncontrolled Recursion). By supplying a crafted JWS containing a deeply nested structure in the header, an attacker can exhaust the CPython call stack. This results in an unhandled interpreter exception that escapes the library's exception wrapper and crashes the active processing thread.

Root Cause Analysis

The vulnerability lies in how the standard Python json.loads decoder operates and how PyJWT handles the errors it raises. The CPython standard library JSON decoder utilizes a recursive-descent parser. When processing nested JSON arrays or dictionaries, the decoder recursively allocates call frames on the interpreter's stack to track state.

If the recursion depth exceeds CPython's execution limit, which is typically governed by the sys.getrecursionlimit() value, the interpreter raises a native RecursionError. In python's class hierarchy, RecursionError inherits from RuntimeError, which in turn inherits from the base Exception class.

In vulnerable version 2.13.0, the PyJWS._load method wrapped the decoding statement in a try-except block that explicitly intercepted only ValueError. Because RecursionError does not inherit from ValueError, it bypassed the exception handler. The exception then bubbled up through the application web server, causing the handling worker to terminate prematurely and return an HTTP 500 error.

Code Analysis & Patch Walkthrough

The vulnerability exists in jwt/api_jws.py inside the internal helper method _load. This method is responsible for splitting the three-part compact token representation, decoding the payload, and reconstructing the Python dictionary representing the header.

Below is the vulnerable implementation of the parsing try-block:

try:
    header: dict[str, Any] = json.loads(header_data)
except ValueError as e:
    raise DecodeError(f"Invalid header string: {e}") from e

Because the block only intercepts ValueError, a RecursionError is raised directly back to the caller. This behavior violates the PyJWT contract, which guarantees that all parsing and encoding anomalies are translated into a subclass of PyJWTError.

The patch remediates this issue by explicitly catching RecursionError alongside ValueError as shown in the diff below:

try:
    header: dict[str, Any] = json.loads(header_data)
except (ValueError, RecursionError) as e:
    raise DecodeError(f"Invalid header string: {e}") from e

This modification ensures that if stack exhaustion occurs during the JSON parsing phase, it is normalized to a standard DecodeError. Web frameworks and application controllers that rely on PyJWT to handle authentication can then gracefully catch DecodeError and issue a standard HTTP 401 or 403 status code.

Exploitation Methodology

Exploitation does not require high technical complexity. An attacker begins by constructing a malformed JSON payload containing deeply nested brackets. For example, an array nested within one thousand other arrays ([[[[...]]]]) is sufficient to exceed standard recursion limits.

[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ ... ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]

The attacker base64url-encodes this nested JSON string to generate the first token segment. They then append two arbitrary strings separated by periods, representing a dummy payload and a dummy signature. This constructs a well-formed compact JWS token layout containing a malicious header.

When the target web service receives the token, it forwards the string to PyJWT. PyJWT attempts to decode the header first. The parser exhausts the execution stack, raises a RecursionError, and crashes the thread. In asynchronous or multi-threaded environments, sending a steady stream of these payloads can exhaust the web server's available thread pool, inducing complete application unavailability.

Impact Assessment

The impact of this vulnerability is a remote, unauthenticated Denial of Service (DoS). Because the header is decoded prior to signature verification, the attacker does not need to possess a valid signing key, access token, or active session on the target application.

While the vulnerability does not allow remote code execution or data extraction, the operational cost of unhandled thread termination can be significant. High-performance web applications running on single-process event loops can experience severe latency spikes or temporary outages if the primary event handler is blocked or terminated.

This vulnerability has been assigned a CVSS v3.1 score of 5.3 (Medium). The vector string is CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L. This reflects network-based availability impact with low attack complexity and no privilege requirements.

Remediation & Defense-in-Depth

The primary remediation is upgrading PyJWT to version 2.14.0 or higher. This version implements the revised exception handling wrapper, converting the raw RecursionError into a library-controlled DecodeError.

For systems where upgrading PyJWT is not immediately viable, a defense-in-depth approach can be deployed. Web application firewalls (WAFs) should be configured to inspect authorization headers and block request parameters containing repeating arrays or dictionary characters before they reach the application interpreter.

Additionally, developers can implement a middleware check that measures the length and structural nesting of the header segment before calling PyJWT. If a token contains more than 50 opening bracket characters, the middleware can reject the transaction outright.

Official Patches

jpadilla (GitHub Releases)PyJWT release containing the fix.

Fix Analysis (1)

Technical Appendix

CVSS Score
5.3/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L
EPSS Probability
0.29%
Top 81% most exploited
15,000
via Censys & Shodan Framework Profiling

Affected Systems

Applications utilizing PyJWT versions between 2.13.0 (inclusive) and 2.14.0 (exclusive) for JWT validation.

Affected Versions Detail

Product
Affected Versions
Fixed Version
PyJWT
jpadilla
>= 2.13.0, < 2.14.02.14.0
AttributeDetail
CWE IDCWE-674 (Uncontrolled Recursion)
Attack VectorNetwork
CVSS Score5.3 (Medium)
EPSS Score0.00291 (0.29%)
Exploit StatusProof of Concept
CISA KEV StatusNot Listed

MITRE ATT&CK Mapping

T1499.004Endpoint Denial of Service: Application Exhaustion Flood
Impact
CWE-674
Uncontrolled Recursion

The software implements a function that calls itself or relies on recursive parsing libraries without restricting the depth of recursion, allowing stack exhaustion.

Known Exploits & Detection

GitHub (PyJWT Test Suite)Official reproduction code confirming stack exhaustion via highly nested brackets.

Vulnerability Timeline

Vulnerability fixed in pyjwt git repository
2026-09-09
PyJWT version 2.14.0 released
2026-09-11
CVE-2026-102265 assigned and published
2026-09-28

References & Sources

  • [1]GitHub Security Advisory GHSA-8wjv-2p76-3863
  • [2]Fix Commit: Handle recursive JWS headers as decode errors
  • [3]CVE-2026-102265 Record (CVE.org)
  • [4]NVD CVE-2026-102265 Detail

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•about 3 hours ago•CVE-2026-128087
3.7

CVE-2026-128087: Premature Key Exchange Callback Invocation Prior to Host Key Verification in russh

CVE-2026-128087 (GHSA-9264-jvgf-6w2f) is an incorrect behavior order (CWE-696) and improper authorization (CWE-863) vulnerability in the russh Rust SSH library, affecting versions 0.55.0 through 0.65.0. During the initial SSH key exchange (KEX) handshake, the client state machine invokes the client::Handler::kex_done() callback—providing the negotiated raw shared secret bytes—prior to validating the remote server's host key or certificate via check_server_key(). Consequently, an untrusted or rogue SSH server can complete cryptographic key agreement and force a connecting client to execute side-effecting application logic inside kex_done() before the server's identity is checked and rejected.

Amit Schendel
Amit Schendel
3 views•10 min read
•about 3 hours ago•CVE-2026-128082
7.5

CVE-2026-128082: Uncontrolled Recursion and Denial of Service in AutoMapper via Constructor Parameter Mapping

CVE-2026-128082 (GHSA-6vhm-j9h7-f9gh) is an uncontrolled recursion vulnerability (CWE-674) in AutoMapper, a convention-based object-object mapper for .NET. When mapping nested or self-referential types into destination models that rely on parameterized constructors, C# positional records, or recursive ConstructUsing expressions, AutoMapper evaluates child constructor arguments prior to incrementing the parent's recursion depth counter. This ordering flaw bypasses both explicit MaxDepth limits and the default depth limit of 64. An unauthenticated remote attacker can supply deeply nested input payloads to affected endpoints, exhausting the thread call stack and triggering an uncatchable System.StackOverflowException that terminates the hosting .NET process.

Amit Schendel
Amit Schendel
5 views•11 min read
•about 5 hours ago•CVE-2026-128080
5.8

CVE-2026-128080: Sensitive Query Parameter Disclosure on Incoming Server Spans in OpenTelemetry JavaScript (@opentelemetry/instrumentation-http)

An information exposure vulnerability in the @opentelemetry/instrumentation-http package for OpenTelemetry JavaScript versions 0.204.0 prior to 0.222.0 causes incoming HTTP server spans to record raw, unredacted query string parameters under the url.query attribute. While outgoing client spans applied built-in and user-configured query parameter redaction, incoming server spans bypassed this sanitization completely, resulting in the transmission of sensitive credentials such as pre-signed cloud URLs and API tokens to external observability backends.

Alon Barad
Alon Barad
4 views•10 min read
•about 6 hours ago•CVE-2026-128089
7.5

CVE-2026-128089: Uncontrolled Resource Consumption in dnspython WKS Record Parser

CVE-2026-128089 is an uncontrolled resource consumption vulnerability in the dnspython toolkit for Python, affecting all versions prior to 2.9.2. When parsing Well-Known Service (WKS) records from text via dns.rdtypes.IN.WKS.WKS.from_text(), the parser fails to validate that numeric service port identifiers fall within the RFC 1035 valid range of 0 through 65535. An attacker capable of supplying untrusted zone files or RDATA text strings containing an arbitrarily large service port integer can force the parser to allocate an unbounded bitmap array using an inefficient linear append loop, resulting in severe CPU exhaustion, application hangs, or Out-Of-Memory (OOM) process termination.

Amit Schendel
Amit Schendel
4 views•10 min read
•about 7 hours ago•CVE-2026-126347
3.1

CVE-2026-126347: Open Redirect via Triple-Slash Redirect Paths in Tornado RedirectHandler

CVE-2026-126347 (GHSA-5cjw-f85j-cv6r) is an open redirect vulnerability (CWE-601) in Tornado, an asynchronous Python networking library and web framework. The flaw resides in tornado.web.RedirectHandler when dynamic URL redirection templates incorporate unvalidated user input. Due to a parser differential between RFC 3986 (used by Python's urllib.parse.urlsplit) and the WHATWG URL Standard (used by modern web browsers), inputs containing three or more leading slashes bypass Tornado 6.6.0's validation logic, allowing unauthenticated attackers to redirect users to arbitrary external domains.

Alon Barad
Alon Barad
5 views•11 min read
•about 8 hours ago•CVE-2026-128123
5.9

CVE-2026-128123: Uncaught Exception and Denial of Service in SvelteKit @sveltejs/adapter-node

A Denial of Service (DoS) vulnerability exists in @sveltejs/adapter-node versions 5.5.7 and 6.0.0-next.0 through 6.0.0. When a SvelteKit server route returns a direct response from a fetch() call with a Content-Type of text/event-stream, the Node.js adapter attempts to mutate the response headers to disable proxy buffering. Because headers returned directly by the WHATWG Fetch API carry an immutable guard, this mutation throws an unhandled TypeError, terminating the underlying Node.js process and denying service to all active and subsequent clients.

Alon Barad
Alon Barad
4 views•9 min read