Jun 15, 2026·6 min read·9 visits
PyJWT eagerly decodes JWS payload segments before validating the b64=false header configuration, enabling an unauthenticated remote Denial of Service attack via large, dummy payload strings.
PyJWT versions 2.8.0 through 2.12.1 are vulnerable to an unauthenticated Denial of Service (DoS) attack. When verifying detached JSON Web Signatures (JWS) using the unencoded-payload option (RFC 7797, b64=false), the library eagerly decodes the payload segment before verifying the header configuration or the cryptographic signature. This behavior enables a remote, unauthenticated attacker to inject an arbitrarily large payload segment, triggering excessive CPU and memory resource consumption prior to signature validation.
PyJWT is a widely deployed Python implementation of the JSON Web Token (JWT) and JSON Web Signature (JWS) specifications. Modern web applications rely on this library to decode, parse, and verify cryptographically signed tokens presented by untrusted external clients. The vulnerability designated as CVE-2026-48525 exposes these applications to unauthenticated denial of service attacks.
The flaw resides in the handling of detached JSON Web Signatures using the unencoded-payload option defined in RFC 7797. When processing these specific tokens, the library fails to properly restrict resource allocation during the parsing stage. An attacker can exploit this oversight to trigger disproportionate CPU and memory consumption on the application server.
This behavior constitutes a classic work amplification attack vector. The target server expends significant computational resources processing malformed or oversized data before executing cryptographic signature validation. Consequently, even requests containing invalid signatures can successfully exhaust system resources and degrade availability.
The root cause of CVE-2026-48525 lies in the order of operations inside the internal JWS parser within jwt/api_jws.py. Specifically, the internal helper function _load() is responsible for deserializing the incoming compact JWS string. This function splits the token into three distinct segments using the period separator: header, payload, and signature.
Under normal operations, the second segment contains the Base64URL-encoded payload of the JWS token. In vulnerable versions, _load() immediately attempts to decode this second segment using the base64url_decode() function. This decoding step occurs before the parser evaluates the protected header parameters.
Under RFC 7797, when the header specifies "b64": false, the inline payload segment of the JWS must be empty. The library is designed to subsequently discard any decoded inline payload and substitute it with a caller-provided detached payload. However, because the decoding step is executed first, the library processes whatever arbitrary data is present in the second segment, regardless of the header setting.
Comparing the vulnerable and patched code paths in jwt/api_jws.py reveals the structural changes introduced in version 2.13.0. In vulnerable versions, the decoding logic was executed blindly within a simple try-except block. This allowed large payloads to be decoded regardless of the header configurations.
The patch introduces conditional checks that inspect the "b64" header parameter before executing the decoding function. If the header specifies that "b64" is false, the library validates that the incoming payload segment is entirely empty. If the segment contains data, the library raises a DecodeError immediately.
Below is the relevant portion of the patch from commit 95791b1759b8aa4f2203575d344d5c78564cdc81:
# Inside PyJWS._load in jwt/api_jws.py
if header.get("b64", True) is False:
# Detached payload form (RFC 7515 Appendix F): the compact-form
# payload segment must be empty; the caller supplies the actual
# payload via the `detached_payload` argument in decode_complete.
# Skipping the base64 decode here removes an unauthenticated work
# amplifier.
if payload_segment:
raise DecodeError(
"Payload segment must be empty when 'b64' is false."
)
payload = b""
else:
try:
payload = base64url_decode(payload_segment)
except (TypeError, binascii.Error) as err:
raise DecodeError("Invalid payload padding") from errIn addition to the decoding check, the patch introduces stricter validation for the "crit" header list. RFC 7797 mandates that if "b64" is set to false in the protected header, it must also be declared inside the "crit" array. This ensures that parsers that do not understand RFC 7797 will reject the token outright.
Exploiting CVE-2026-48525 requires minimal effort and no authentication. An attacker must identify an application endpoint that accepts detached JWS tokens with unencoded payloads. Because the signature check occurs after the payload decoding step, the attacker does not need a valid cryptographic key.
The attacker constructs a JWS header containing "alg", "b64": false, and "crit": ["b64"]. Instead of leaving the payload segment empty as required by the specification, the attacker inserts a very large block of random Base64URL characters. This string is appended between the header and a dummy signature.
When the server receives the malformed token, the Python interpreter begins allocating memory and utilizing CPU cycles to decode the massive string. If multiple concurrent requests are dispatched, the target server's worker processes will rapidly become saturated. This leads to severe latency or termination via out-of-memory errors.
> [!NOTE] > Because PyJWT is frequently deployed in synchronous Python web frameworks, a single worker process can be blocked entirely while parsing a single malicious token. This amplification effect makes the vulnerability highly efficient for attackers.
The primary impact of CVE-2026-48525 is a localized Denial of Service on the affected application. The vulnerability is assigned a CVSS v3.1 score of 5.3, reflecting a medium severity impact. The attack vector is remote and requires no privileges, giving it a low complexity threshold. While there is no impact on confidentiality or integrity, the availability of the application is degraded.
Systems that run memory-constrained container environments are particularly vulnerable to crashing. When the Python memory allocator attempts to handle multiple concurrent multi-megabyte string decoding operations, the operating system kernel may terminate the process. This causes immediate service disruption for all legitimate users.
Currently, there is no evidence of active exploitation in the wild. However, proof-of-concept analysis indicates that generating an exploit requires minimal technical sophistication.
The standard remediation path is upgrading the PyJWT dependency to version 2.13.0 or higher. This version implements the necessary validation checks to discard non-compliant tokens before executing expensive decoding steps. Software developers should update their requirements files and rebuild container images accordingly.
For environments where immediate updates are not feasible, temporary workarounds can mitigate the risk. Implementing strict input validation filters on incoming request sizes at the reverse proxy or API gateway level is highly recommended. Limiting the maximum allowed length of HTTP authorization headers can block large payloads.
Network monitoring tools and Web Application Firewalls can be configured to inspect JWS patterns. Requests containing extremely large JWS headers or payload segments that do not conform to expected application constraints should be dropped. Developers should also audit their codebase to verify whether the detached_payload parameter is used in their JWS parsing implementations.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L| Product | Affected Versions | Fixed Version |
|---|---|---|
PyJWT PyJWT Project | >= 2.8.0, <= 2.12.1 | 2.13.0 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-400 |
| Attack Vector | Network (AV:N) |
| CVSS Score | 5.3 (Medium) |
| Exploit Status | PoC Analysis / None |
| KEV Status | Not Listed |
The program does not properly control the allocation and maintenance of a limited resource on behalf of an actor, enabling a Denial of Service.
An authentication bypass in the SiYuan personal knowledge management system before version 3.7.0 exposes a dynamic icon rendering endpoint. This endpoint processes client-supplied Go template directives. By submitting a crafted request, an unauthenticated remote attacker can leverage registered database template functions to execute arbitrary read-only SQL queries and exfiltrate workspace contents.
CVE-2026-54069 is a critical authentication bypass vulnerability in the SiYuan Note personal knowledge management system. The flaw is located in the HTTP server's middleware handling API authorization, which unconditionally trusts requests carrying a 'chrome-extension://' scheme in the Origin HTTP header, granting administrative access without validating API tokens.
CVE-2026-54089 is a critical authentication bypass vulnerability in File Browser affecting instances configured with proxy-based authentication. An unauthenticated remote attacker with direct network access can impersonate arbitrary users or register new accounts by spoofing configured HTTP headers.
The malicious Cargo package 'exploration' was uploaded to the crates.io registry. During compilation or package import, the crate executes code designed to establish an outbound TCP/HTTP connection, download an external second-stage binary, and execute the binary locally on the host machine. This creates an unauthenticated remote code execution vector impacting developer environments and continuous integration pipelines.
CVE-2026-54088 is a critical command injection vulnerability in File Browser prior to version 2.63.6. When Hook Authentication is enabled, the application interpolates unsanitized credentials into a shell command, allowing unauthenticated remote code execution.
An authenticated remote code execution vulnerability exists in NotrinosERP (versions up to and including 1.0.0) within the Human Resource Management (HRM) module. Users with employee management permissions can upload arbitrary file types, including PHP scripts, which are written directly to a web-accessible directory. This allows for arbitrary code execution in the context of the web-server user.