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-59881

CVE-2026-59881: Unnegotiated WebSocket RSV1 Frame Handling in aiohttp

Amit Schendel
Amit Schendel
Senior Security Researcher

Aug 4, 2026·6 min read·85 visits

Executive Summary (TL;DR)

A vulnerability in the aiohttp WebSocket client allows malicious servers to bypass client configuration and force decompression of server-supplied payloads. This occurs because the parser improperly defaults to accepting compressed frames even when the permessage-deflate extension was not negotiated, allowing attackers to trigger a Denial-of-Service (DoS) condition via decompression bombs.

CVE-2026-59881 is a protocol compliance and input validation vulnerability in the client-side WebSocket implementation of the aiohttp asynchronous HTTP client/server framework for Python. Prior to version 3.14.2, the framework's parser unexpectedly accepts and attempts to decompress frames containing the RSV1 bit, even when the permessage-deflate extension has not been negotiated during the initial WebSocket handshake. This violation of RFC 6455 allows a malicious or compromised server to bypass client configuration, forcing decompression routines that can lead to high CPU and memory consumption, resulting in a denial-of-service condition.

Vulnerability Overview

CVE-2026-59881 is an input validation and protocol compliance vulnerability in the client-side WebSocket parsing architecture of the aiohttp framework. The defect exists within the frame-processing engine, which fails to correctly enforce RFC 6455 specifications governing the use of reserved bits. Specifically, the parser does not validate whether the RSV1 bit in incoming WebSocket headers has been mutually negotiated during the connection upgrade handshake.

According to RFC 6455, the RSV1 bit is reserved for extension negotiations, most notably the permessage-deflate compression protocol defined in RFC 7692. If this extension is not explicitly established, receiving a frame with RSV1 set to 1 represents an invalid state. The specification mandates that the receiver must fail the connection immediately with close code 1002 (Protocol Error) upon encountering this condition.

In affected versions of aiohttp, the client fails to reject these unauthorized frames. Instead, the frame parser accepts the payload and passes it directly to the internal zlib decompression routine. This defect exposes the client to unexpected, server-controlled decompression tasks, which can be leveraged by a malicious remote host to exhaust client system resources.

Root Cause Analysis

The root cause of CVE-2026-59881 lies in the default constructor configuration of the WebSocketReader class and its subsequent instantiation pattern. Located in aiohttp/_websocket/reader_py.py, the WebSocketReader is responsible for decoding bytes from the underlying TCP socket and assembling them into distinct WebSocket messages.

The class constructor signature was designed with a default value of True for its internal compress flag. This configuration assumed that decompression capability should be active unless explicitly deactivated by the caller. This default value created a fallback state that bypassed proper state verification during connection establishment.

During connection setup in aiohttp/client.py:_ws_connect, the client initiates the reader but omits the compress argument. Because of this omission, the initialized WebSocketReader operates with compress=True regardless of the negotiated handshake. When the client receives a frame with the RSV1 bit set, it reads the local _compress flag, finds it active, and executes decompression rather than throwing a Protocol Error as mandated by RFC 6455.

Code Analysis

An analysis of the vulnerable code paths demonstrates the mechanics of the fallback error. In aiohttp/_websocket/reader_py.py, the vulnerable signature was declared as follows:

# Vulnerable implementation in aiohttp/_websocket/reader_py.py
def __init__(
    self,
    queue: WebSocketDataQueue,
    max_msg_size: int,
    compress: bool = True,       # Defect: Defaults to True
    decode_text: bool = True,
) -> None:
    self._compress = compress
    # ... parser state setup ...

When the client-side connection helper _ws_connect initiated this parser, it did not explicitly supply the status of the compress variable derived from the handshake parameters:

# Vulnerable instantiation in aiohttp/client.py
# The local 'compress' variable is defined but not passed to the constructor
parser = WebSocketReader(reader, max_msg_size, decode_text=decode_text)

The patch resolved this discrepancy by removing the default value from the WebSocketReader signature, rendering the configuration parameter mandatory:

# Patched implementation in aiohttp/_websocket/reader_py.py
def __init__(
    self,
    queue: WebSocketDataQueue,
    max_msg_size: int,
    compress: bool,              # Fix: Default value removed
    decode_text: bool,
) -> None:
    self._compress = compress

The client upgrade routine was corrected to explicitly map the negotiated state to the reader initialization. This ensures that when compression is not negotiated, compress evaluates to False, forcing the reader to flag incoming RSV1 frames as protocol violations:

# Patched instantiation in aiohttp/client.py
parser = WebSocketReader(
    reader,
    max_msg_size,
    compress=bool(compress),     # Fix: Explicitly pass handshake setting
    decode_text=decode_text,
)

Exploitation Methodology

Exploitation of CVE-2026-59881 requires a malicious or compromised WebSocket server to which the vulnerable client initiates a connection. It is also possible for a Man-in-the-Middle (MitM) attacker on an unencrypted ws:// connection to intercept and inject the malicious frames into the stream.

The attack begins during the initial WebSocket HTTP upgrade handshake. The client initiates a connection, and the server accepts the upgrade but omits the Sec-WebSocket-Extensions: permessage-deflate header from the response. The client assumes the connection is established without compression support, yet due to the bug, its frame parser remains configured to accept and decompress frames.

Once the handshake is completed, the server transmits a crafted WebSocket frame where the RSV1 bit in the first byte is set to 1. The payload of this frame is structured as a valid zlib/deflate payload. Crucially, the payload is crafted as a decompression bomb (zip bomb), containing highly repetitive, highly compressible byte patterns designed to expand dramatically upon processing.

When the vulnerable client receives this frame, it passes the compressed bytes directly to zlib.decompress. The decompression process consumes massive CPU resources to process the stream and causes a sudden escalation in memory allocation. This resource spike degrades application performance, stalls asynchronous event loops, and typically triggers an out-of-memory (OOM) termination of the client process.

Impact Assessment

The impact of CVE-2026-59881 is classified as a remote denial of service (DoS) and resource exhaustion vulnerability affecting systems that deploy the aiohttp client. This vulnerability does not lead to remote code execution, privilege escalation, or unauthorized access to sensitive application data.

Because the defect is situated within the client-side implementation, the vulnerability is only triggered when the client actively establishes a connection to a hostile endpoint. This limits the threat surface primarily to applications that interact with external, dynamic, or user-provided WebSocket targets, such as crawler bots, feeds, or messaging clients.

The CVSS v4.0 score of 6.9 reflects medium severity, acknowledging that while the impact on system availability is low (restricted to the client application process), the attack complexity is low and requires no user interaction. There is currently no evidence of active exploitation in the wild, and the known exploit is limited to a proof-of-concept functional test within the project's repository.

Remediation and Mitigation

The standard remediation is upgrading the aiohttp library to version 3.14.2 or higher. This update resolves the unsafe initialization defaults and implements strict RFC 6455 validation for the RSV1 bit. You can perform the upgrade through Python's package manager:

pip install -U "aiohttp>=3.14.2"

If upgrading is not immediately possible, application developers should implement defensive controls to limit exposure. Restrict outbound WebSocket connections to validated, trusted domains. Avoid connecting to unencrypted ws:// schemes where data modification by network intermediaries is possible.

Additionally, deploy container-level resource limits (such as cgroup memory limits) to restrict the physical resources available to the application process. This ensures that if a client is targeted by a decompression bomb, the resulting resource consumption is contained and cannot exhaust the entire host system's memory or CPU allocation.

Official Patches

aio-libsOfficial security patch in aiohttp repository
aio-libsSecurity fix pull request detailing bug validation and code changes

Fix Analysis (1)

Technical Appendix

CVSS Score
6.9/ 10
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N
EPSS Probability
0.30%
Top 77% most exploited

Affected Systems

aiohttp client-side WebSocket reader implementations prior to v3.14.2

Affected Versions Detail

Product
Affected Versions
Fixed Version
aiohttp
aio-libs
< 3.14.23.14.2
AttributeDetail
CWE IDCWE-20
Attack VectorNetwork
CVSS v4.0 Score6.9 (Medium)
EPSS Score0.00302
ImpactDenial of Service (DoS) / Resource Exhaustion
Exploit StatusProof-of-Concept
CISA KEV StatusNot Listed

MITRE ATT&CK Mapping

T1190Exploit Public-Facing Application
Initial Access
CWE-20
Improper Input Validation

The product does not validate or incorrectly validates input that can affect the control flow or data flow of a program.

Known Exploits & Detection

GitHub Security Advisory TestsFunctional regression test showcasing frame injection and client failure state validation.

Vulnerability Timeline

Security fix committed to the aio-libs/aiohttp stable branches
2026-06-23
GitHub Security Advisory published
2026-07-30
CVE-2026-59881 registered and published to the NVD
2026-07-30
Official release of version 3.14.2 containing the patch
2026-07-30

References & Sources

  • [1]NVD Entry for CVE-2026-59881
  • [2]GitHub Security Advisory GHSA-mq44-7p77-q5h7
  • [3]aiohttp Release Tag v3.14.2

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

•3 minutes ago•CVE-2026-107723
8.1

CVE-2026-107723: Silent Claim-Validator Bypass in NearForm fast-jwt via Array Payload Type Confusion

A high-severity type-confusion vulnerability exists in NearForm fast-jwt prior to version 6.3.0. The vulnerability allows attackers to bypass crucial claim validation steps (such as expiration, issuer, audience, and subject validations) by presenting a validly signed JSON Web Token structured as a JSON array instead of a JSON object. This occurs because the library's decoder fails to reject JSON arrays during type evaluation.

Alon Barad
Alon Barad
0 views•6 min read
•about 1 hour ago•CVE-2026-107721
5.9

CVE-2026-107721: Time Validation Bypass in NearForm fast-jwt due to Loose Temporal Option Validation

NearForm fast-jwt prior to version 6.3.0 is vulnerable to an input validation flaw where configuring verifier properties (such as clockTolerance, clockTimestamp, and cacheTTL) with non-finite values like Infinity or NaN allows attackers to bypass temporal claim validations, including expiration (exp) and activation (nbf) boundaries. This validation bypass can result in unauthorized session persistence and cache poisoning.

Amit Schendel
Amit Schendel
2 views•6 min read
•about 2 hours ago•CVE-2026-107722
9.8

CVE-2026-107722: Algorithm Confusion via Non-Whitespace Prefix Bypass in fast-jwt

A critical cryptographic vulnerability in fast-jwt versions 6.2.x prior to 6.3.0 allows unauthenticated remote attackers to execute an asymmetric-to-symmetric algorithm confusion attack due to incomplete validation of leading non-whitespace prefixes.

Amit Schendel
Amit Schendel
2 views•5 min read
•about 3 hours ago•CVE-2026-107720
7.4

CVE-2026-107720: Signature Verification Bypass in NearForm fast-jwt

CVE-2026-107720 is a critical signature verification bypass vulnerability in NearForm's fast-jwt Node.js library. Under specific configurations where the token verifier is initialized with a falsy cryptographic key (such as an empty string or null) and a non-empty algorithms allowlist, the library erroneously skips signature validation. This allows unauthenticated remote attackers to submit fabricated, unsigned JSON Web Tokens and bypass the authorization boundary of the application entirely.

Amit Schendel
Amit Schendel
5 views•7 min read
•about 4 hours ago•CVE-2026-107715
6.8

CVE-2026-107715: Information Disclosure and Credential Leakage in Ruby Mechanize via Cross-Origin Redirections

Ruby Mechanize prior to version 2.14.1 contains an information disclosure vulnerability. When executing cross-origin HTTP redirects, global headers configured on the Mechanize agent (such as Authorization or Session Cookies) are dynamically re-applied to the subsequent request, bypassing the internal header-stripping logic. An attacker who controls a redirection endpoint can capture sensitive bearer tokens or cookies.

Alon Barad
Alon Barad
6 views•7 min read
•about 5 hours ago•CVE-2026-107399
6.8

CVE-2026-107399: Information Disclosure via HTML Meta-Refresh in Ruby Mechanize

An origin trust boundary failure in the Ruby mechanize library (prior to v2.14.1) allows unauthenticated remote web servers to harvest sensitive global request headers, such as Authorization Bearer tokens and cookies, by utilizing HTML-level meta-refresh redirection tags. Standard HTTP-level redirect boundaries were not applied to document-level redirects, creating a vector for cross-origin credential leakage during automated crawls.

Amit Schendel
Amit Schendel
5 views•5 min read