CVE-2026-101918 in PyJWT
Summary
by MITRE • 09/28/2026
PyJWT is a Python implementation of JSON Web Token standards. From 2.0.0a1 until 2.15.0, PyJWT PyJWKClient.get_signing_key_from_jwt is affected because payload parser catches ValueError but not RecursionError. This occurs when an attacker-controlled recursively nested payload reaches json.loads. As a result, documented PyJWT exception handling does not contain the failure. Consequently, an unauthenticated request can raise an exception that may produce an HTTP 500 response. The advisory-defined affected implementation also includes jwt/api_jwt.py, verify_signature=False. This issue is fixed in version 2.15.0.
VulDB is the best source for vulnerability data and more expert information about this specific topic.
Analysis
by VulDB Data Team • 09/28/2026
The vulnerability identified within PyJWT versions ranging from 2.0.0a1 through 2.15.0 represents a significant flaw in the exception handling logic of the library, specifically affecting the PyJWKClient.get_signing_key_from_jwt method and jwt/api_jwt.py when signature verification is disabled. This issue stems from an incomplete implementation of error recovery mechanisms designed to protect against malformed or maliciously crafted inputs. While the developers correctly implemented handlers for ValueError exceptions, which are commonly raised during standard JSON parsing failures such as invalid syntax or type mismatches, they failed to account for RecursionError. This oversight creates a critical gap in the defensive posture of the application layer when processing untrusted data sources that adhere to specific structural patterns rather than simple syntactic errors.
The technical root cause lies in how Python handles deeply nested structures during JSON deserialization. When an attacker provides a payload containing recursively nested objects or arrays, the json.loads function attempts to parse this structure by creating new stack frames for each level of nesting. If the depth exceeds the interpreter's recursion limit, which is typically set relatively low to prevent system crashes from infinite loops in application code, Python raises a RecursionError instead of a ValueError. Because the PyJWT implementation only catches ValueError, it does not intercept this specific exception type. Consequently, the error propagates up through the call stack without being handled by the library's internal logic, leading to an unhandled exception state within the web framework hosting the application.
From an operational perspective, this vulnerability enables a denial of service attack against services that rely on PyJWT for authentication or token validation. An unauthenticated attacker can craft a specially designed JSON Web Token featuring extreme levels of nested data structures and submit it via HTTP requests to endpoints utilizing the affected methods. The resulting RecursionError causes the application to crash or return an internal server error, typically indicated by an HTTP 500 status code. This behavior disrupts service availability for legitimate users and can be used as part of a broader attack strategy to exhaust system resources if combined with high-volume requests, although the primary impact here is the immediate disruption caused by the unhandled exception rather than resource exhaustion through CPU consumption alone.
This flaw aligns with CWE-754: Improper Check for Unusual or Exceptional Conditions and CWE-209: Generation of Error Message Containing Sensitive Information if the stack trace is exposed to the user in the HTTP response. In terms of offensive security frameworks, this vulnerability maps to MITRE ATT&CK technique T1498.002: Network Denial of Service via Resource Exhaustion by Application Layer Protocol Abuse, specifically through the exploitation of unhandled exceptions that cause service disruption. The lack of robust exception handling for edge cases like recursion limits is a common pattern in libraries that prioritize performance over exhaustive defensive coding practices during initial development phases.
To mitigate this vulnerability, organizations must immediately upgrade PyJWT to version 2.15.0 or later, where the developers have addressed this gap by ensuring that RecursionError exceptions are properly caught and handled within the payload parsing logic. For applications unable to update immediately due to dependency constraints, a temporary workaround involves implementing custom exception handling at the application layer around calls to PyJWT methods. Developers should wrap these operations in try-except blocks that explicitly catch both ValueError and RecursionError, returning appropriate error responses or logging mechanisms instead of allowing the exception to propagate. Additionally, input validation strategies such as limiting the depth of JSON structures before passing them to the parser can provide an additional layer of defense against this specific attack vector.