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

CVE-2026-69243: HTTP Request Smuggling via WebSocket Upgrade State Desynchronization in aiohttp

Amit Schendel
Amit Schendel
Senior Security Researcher

Aug 4, 2026·8 min read·19 visits

Executive Summary (TL;DR)

Prior to version 3.14.2, aiohttp transitions its protocol state to 'upgraded' before reading the body of a WebSocket upgrade request. If the handler rejects the upgrade, any unconsumed body bytes are parsed as a new pipelined HTTP request, enabling request smuggling.

An asynchronous HTTP client/server framework for asyncio and Python, aiohttp prior to version 3.14.2 is vulnerable to HTTP Request Smuggling. The server-side HTTP parser immediately transitions the protocol state to 'upgraded' upon receiving a WebSocket upgrade request before consuming the accompanying request body. If the backend handler rejects the upgrade request while keeping the TCP connection alive, the unconsumed request body remains in the socket buffer and is parsed as a subsequent pipelined HTTP request. This allows an attacker to smuggle requests, bypass frontend reverse proxy controls, and perform unauthorized actions.

Vulnerability Overview

The vulnerability CVE-2026-69243 resides in the server-side HTTP parser of the aiohttp framework, an asynchronous HTTP client/server implementation for Python. The affected component is responsible for processing incoming HTTP requests, determining message boundaries, and managing state transitions such as protocol upgrades. The attack surface is exposed to any network-accessible interface running an aiohttp server that handles HTTP/1.1 pipelined connections or uses reverse proxies.\n\nUnder normal conditions, a client initiates a WebSocket connection by sending an HTTP GET request containing 'Connection: Upgrade' and 'Upgrade: websocket' headers. The parser must process the headers, determine if a body exists, consume the body if present, and then hand over the socket to the WebSocket handler. This transition must adhere strictly to RFC 9110 Section 7.8, which mandates that a server must not switch protocol states until the entire upgrade request has been fully read and processed.\n\nThe vulnerability occurs because the aiohttp server-side parser transitions the socket state to 'upgraded' prior to consuming the request body. If the application-level handler rejects the WebSocket upgrade (for instance, due to failed authentication or missing headers) and sends an HTTP error response, the connection remains open. Because the upgrade state was set prematurely, the parser ignores the declared request body, leaving those bytes in the TCP socket's read buffer to be parsed as a subsequent request. This inconsistent interpretation of message boundaries leads to HTTP Request Smuggling (CWE-444).

Root Cause Analysis

The root cause of this vulnerability lies in the early assignment of the state variable self._upgraded = True inside the HTTP parsing logic of both the Cython-based parser (aiohttp/_http_parser.pyx) and the fallback pure-Python parser (aiohttp/http_parser.py). This early assignment occurs during the header-parsing phase, immediately when the Upgrade header is identified, rather than waiting for the payload parser to finish consuming the request body.\n\nWhen self._upgraded is set to True during header processing, the standard HTTP body framing checks are bypassed. The parser logic assumes that the connection has switched to a non-HTTP protocol (e.g., WebSocket binary frames) and stops looking for standard HTTP body framing such as Content-Length or chunked transfer encoding. However, the client has sent a body payload as part of the upgrade request. Since the server does not consume this body, the unconsumed bytes remain buffered in the socket.\n\nIf the application handler rejects the upgrade request, it returns a standard HTTP error response (e.g., 400 Bad Request) over the active TCP connection. The connection remains open if keep-alive is active. When the client sends another request, or when the server processes the next message in the pipeline, the server's parser is reset to the HTTP state. It reads the remaining socket buffer, which contains the unconsumed body of the previous upgrade request, and mistakenly interprets this body as a new, independent HTTP request sent by the client. This mismatch between proxy-level framing and backend-level framing allows request smuggling.

Code Analysis

The security advisory and patch commit 6ae358f0983c3f4d6f67692b2f8e65dc8e091c98 demonstrate the differences between the vulnerable and patched code paths. In the vulnerable version, the Cython parser in _http_parser.pyx set _upgraded = True inside the header processing block:\n\npython\n# Vulnerable code path in _http_parser.pyx\nif (upgrade and h_upg.isascii() and h_upg.lower() in ALLOWED_UPGRADES) or self._cparser.method == cparser.HTTP_CONNECT:\n self._upgraded = True\n\n\nThe patch replaces this premature assignment with a deferred state variable _pending_upgrade. The modified code prevents the parser from switching to the upgraded state until the body parser has explicitly finished reading the HTTP request body:\n\npython\n# Patched code path in _http_parser.pyx\nif (upgrade and h_upg.isascii() and h_upg.lower() in ALLOWED_UPGRADES) or self._cparser.method == cparser.HTTP_CONNECT:\n # Defer the protocol switch until the complete request has been received\n self._pending_upgrade = True\n\n\nSimilarly, in the pure-Python fallback implementation (http_parser.py), the assignment self._upgraded = msg.upgrade and _is_supported_upgrade(msg.headers) was removed from the header parsing stage. Instead, self._pending_upgrade is set if a body payload parser is created. Once the payload parser completes its processing and reads the body to completion, the parser transitions self._upgraded = True and clears self._pending_upgrade:\n\npython\n# Execution block when payload parser finishes reading\nif self._pending_upgrade:\n # Body fully read: the deferred upgrade takes effect and the rest of the connection is the upgraded protocol\n self._upgraded = True\n self._pending_upgrade = False\n\n\nThis deferred state transition ensures complete compliance with RFC 9110 by guaranteeing that all body bytes are drained from the stream before any protocol-switching mechanics are activated. If the application handler subsequently rejects the upgrade, no unconsumed body bytes remain in the socket buffer to corrupt the next HTTP parser cycle.

Exploitation Methodology

Exploitation of CVE-2026-69243 requires an environment where an aiohttp server is deployed behind a reverse proxy that supports HTTP/1.1 pipelining and WebSocket connections. The attacker must target an endpoint on the backend aiohttp server that is programmed to reject WebSocket upgrades. This scenario commonly occurs when WebSocket routes require authentication tokens or specific headers that the attacker intentionally omits or invalidates.\n\nTo perform the attack, the attacker transmits a crafted HTTP/1.1 request designed to look like a WebSocket upgrade to the reverse proxy. This request includes a Content-Length header specifying the size of a smuggled request payload contained in the body. The reverse proxy reads the request and the accompanying body, forwarding the entire stream to the backend server. The vulnerable backend aiohttp parser parses the headers, immediately switches to the upgraded state, and ignores the body. The application handler then processes the request and rejects the upgrade because of the invalid headers, sending an HTTP 403 response.\n\nBecause the backend failed to read the body, the smuggled request bytes remain in the TCP read buffer. When the backend server prepares to read the next pipelined HTTP request on the persistent connection, it reads these buffered bytes and executes the smuggled command. The diagram below illustrates this flow of execution:\n\nmermaid\ngraph LR\n Attacker["Attacker"] -->|"1. Sends Upgrade Request with Body"| Proxy["Reverse Proxy"]\n Proxy -->|"2. Forwards entire payload"| Backend["aiohttp (< 3.14.2)"]\n Backend -->|"3. Sets upgraded=True prematurely"| Parser["Parser State"]\n Backend -->|"4. App rejects upgrade, returns 403"| Client["Connection Left Open"]\n Parser -->|"5. Leftover body bytes remain in socket"| Buffer["Socket Read Buffer"]\n Backend -->|"6. Reads next request from socket"| Smuggled["Smuggled HTTP Request Executed"]\n\n\nSince the smuggled request appears to originate from the connection established between the trusted reverse proxy and the backend, it bypasses any access control rules, path restrictions, or security filters implemented solely at the reverse proxy layer.

Impact Assessment

The impact of successful exploitation is critical for applications that rely on frontend reverse proxies for access control, path-based routing, or request filtering. By successfully smuggling requests, an unauthenticated network attacker can execute arbitrary HTTP methods on the backend server. This allows them to access restricted administrative endpoints (e.g., /admin), perform unauthorized data modifications, or retrieve sensitive configuration resources.\n\nThe vulnerability is classified as Medium severity with a CVSS v4.0 score of 6.3. The vector string is CVSS:4.0/AV:N/AC:H/AT:N/PR:N/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N. This score reflects the high complexity (AC:H) required to successfully align the socket states and exploit timing characteristics, coupled with low integrity impacts (VI:L). There is no direct confidentiality or availability impact defined in the CVSS vector, although real-world consequences depend heavily on the specific endpoints exposed by the backend application.\n\nCurrently, the exploit maturity of this vulnerability is classified as 'unproven' or 'none'. No weaponized exploit payloads or public automated scanning templates have been identified in the wild, and the vulnerability is not listed in the CISA Known Exploited Vulnerabilities (KEV) catalog. However, because the public regression tests serve as a structural blueprint, security teams must assume that custom exploit chains can be developed by sophisticated actors.

Remediation and Mitigation

The primary remediation for CVE-2026-69243 is to upgrade the aiohttp dependency to version 3.14.2 or higher. This update introduces the deferred protocol upgrade state logic, ensuring that the request body is always consumed prior to switching protocols. This completely eliminates the socket state desynchronization vector.\n\nIf upgrading the library is not immediately feasible, organizations must deploy defensive configurations at the reverse proxy or Web Application Firewall (WAF) layer. A highly effective mitigation is to block any incoming HTTP request that contains both a WebSocket upgrade header and a request body. Because standard WebSocket handshakes (RFC 6455) are GET requests and do not contain bodies, any upgrade request containing a Content-Length greater than zero or a Transfer-Encoding: chunked header should be treated as anomalous and rejected at the perimeter.\n\nAdditionally, security teams can implement strict connection management policies on the reverse proxy. Disabling HTTP keep-alive or connection reuse for backend connections that handle WebSocket handshakes prevents pipelined request processing. If the connection is closed immediately after the backend returns an error response, the buffered smuggled bytes will be discarded along with the closed socket, neutralizing the attack path.

Official Patches

aio-libsGitHub Security Advisory GHSA-mfx4-hv73-q22v
aio-libsFix commit in GitHub repository

Fix Analysis (1)

Technical Appendix

CVSS Score
6.3/ 10
CVSS:4.0/AV:N/AC:H/AT:N/PR:N/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N
EPSS Probability
0.01%
Top 100% most exploited

Affected Systems

aiohttp asynchronous server component

Affected Versions Detail

Product
Affected Versions
Fixed Version
aiohttp
aio-libs
< 3.14.23.14.2
AttributeDetail
CWE IDCWE-444
Attack VectorNetwork (AV:N)
CVSS VectorCVSS:4.0/AV:N/AC:H/AT:N/PR:N/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N
Exploit Statuspoc
KEV StatusNo
Affected ComponentHTTP Parser

MITRE ATT&CK Mapping

T1190Exploit Public-Facing Application
Initial Access
T1505Server Software Component
Persistence
CWE-444
Inconsistent Interpretation of HTTP Requests ('HTTP Request/Response Smuggling')

The application parses or interprets HTTP requests in a way that is inconsistent with a proxy or other intermediate device, enabling request smuggling attacks.

Known Exploits & Detection

aiohttp regression testsThe official test suite contains regression tests verifying the vulnerability path by pipelining a request behind a rejected websocket upgrade request.

Vulnerability Timeline

Security patch committed to the repository
2026-06-30
aiohttp version 3.14.2 released
2026-08-03
GitHub Security Advisory GHSA-mfx4-hv73-q22v published
2026-08-03
CVE-2026-69243 officially assigned and published
2026-08-03

References & Sources

  • [1]GitHub Security Advisory GHSA-mfx4-hv73-q22v
  • [2]Official Pull Request #13017
  • [3]Commit 6ae358f0983c3f4d6f67692b2f8e65dc8e091c98
  • [4]Release v3.14.2
  • [5]CVE Record

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

•44 minutes 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
•about 6 hours ago•CVE-2026-107718
6.1

CVE-2026-107718: Open Redirect Vulnerability in @adonisjs/http-server

CVE-2026-107718 is a medium-severity Open Redirect vulnerability in the core HTTP server package of the AdonisJS Node.js framework. Prior to versions 8.2.3 and 9.3.0, the framework built route paths by directly interpolating dynamic parameters and wildcard segments without URI encoding. If an application routes attacker-controlled input directly to a dynamic first path segment and uses the generated route URL as a redirect destination, a leading slash can produce a scheme-relative external URL. Modern web browsers process scheme-relative URLs by redirecting the client to the specified external domain, exposing users to credential harvesting, social engineering, and session hijacking. This vulnerability affects all applications running unpatched configurations where input validation is not explicitly implemented before generating paths.

Alon Barad
Alon Barad
6 views•6 min read