CVE-2024-52304
NoneCVSS
—
EPSS
0.6%
Published
Nov 18, 2024
CISA due date
—
Cloudanix analysis
Some Python web services may misread specially crafted web requests, allowing attackers to slip hidden requests past protective gateways unless the software is updated.
- Exploitation
- Remote Unauthenticated
- Attacker needs
- None
- Complexity
- Moderate
- Impact
- Lateral Movement
- Component
- Web Framework
- Class
- Improper Input Validation
- Remediation
- Upgrade
- Effort
- Medium
- Patch risk
- Low
What it actually does
The flaw is an HTTP request parsing inconsistency in aiohttp versions prior to 3.10.11 when the pure-Python HTTP parser is used instead of the C extensions, including deployments where AIOHTTP_NO_EXTENSIONS is enabled. The parser mishandles newline characters inside HTTP chunk extensions, which can cause aiohttp and an upstream proxy, firewall, load balancer, or gateway to disagree about where one HTTP request ends and the next begins. Under the right proxying conditions, this can enable HTTP request smuggling, allowing an attacker to hide or prepend a second request that is interpreted differently by backend services than by front-end controls.
Why it matters to the business
Successful exploitation can let an attacker bypass front-end security controls, routing rules, authentication assumptions, web application firewall checks, or cache boundaries for affected aiohttp-based services. The most serious outcomes depend on the application and deployment topology, but may include unauthorized access to internal endpoints, session confusion, cache poisoning, request tampering, or reaching functionality that operators expected to be protected by a proxy. This issue is not listed in CISA KEV, is not currently associated with ransomware use, and has a low EPSS score, but it has been public for an extended period and should still be remediated wherever aiohttp is exposed through reverse proxies or API gateways.
How an attack unfolds
An attacker targets an aiohttp service that receives HTTP traffic through a front-end proxy, gateway, WAF, CDN, or load balancer. The attacker sends a crafted HTTP/1.1 request using chunked transfer encoding with a malformed chunk extension containing newline characters. Because the vulnerable pure-Python aiohttp parser and the front-end component may parse the malformed chunked body differently, the front end may believe it has forwarded one well-formed request while the aiohttp backend interprets additional bytes as a separate or altered request. The attacker can then attempt to smuggle a hidden request to a backend-only path, bypass front-end filtering, poison a cache entry, desynchronize a connection used by another request, or manipulate how the application processes subsequent traffic. Exploitability depends heavily on use of the pure-Python parser, HTTP/1.1 keep-alive behavior, proxy buffering behavior, and whether sensitive backend routes are reachable through the same connection path.
How to fix it
Upgrade aiohttp to version 3.10.11 or later. For source-based deployments, ensure the code includes the upstream fix commit 3e09325e4839117df13fbac301f360edf8d3a0ee. Rebuild and redeploy application containers or virtual environments so the runtime package actually uses the patched aiohttp version. Where immediate upgrade is not possible, prefer enabling and validating the normal aiohttp C extensions rather than the pure-Python parser, remove any AIOHTTP_NO_EXTENSIONS setting, and block or normalize malformed chunked requests at the edge. Additional compensating controls include disabling HTTP/1.1 keep-alive between front-end proxies and aiohttp backends where operationally acceptable, rejecting requests with chunk extensions at the proxy layer, enforcing strict HTTP request normalization, and ensuring backend-only administrative routes are not reachable through the same public listener.
How to confirm the fix worked
Confirm package inventory shows aiohttp 3.10.11 or later in every runtime image, virtual environment, and dependency lockfile. Validate with commands such as `python -c "import aiohttp; print(aiohttp.__version__)"` inside the deployed runtime, not only in source control. Check deployment configuration, container environment, service files, and orchestration manifests for AIOHTTP_NO_EXTENSIONS and remove it unless there is a documented operational reason. Confirm the installed aiohttp build includes compiled extensions where expected. At the network layer, test that the front-end proxy rejects or safely normalizes HTTP/1.1 chunked requests containing malformed chunk extensions with embedded newline characters. Review reverse proxy behavior for request buffering, connection reuse, and backend keep-alive settings. A successful fix should eliminate parser desynchronization behavior and should not allow a crafted chunked request to produce different request interpretation between the proxy and backend.
Typical attack path
- Identify an internet-facing or proxy-exposed service built with aiohttp before version 3.10.11.
- Determine whether the deployment is likely using the pure-Python parser, such as because aiohttp C extensions are unavailable or AIOHTTP_NO_EXTENSIONS is enabled.
- Send probing HTTP/1.1 requests using Transfer-Encoding: chunked and unusual chunk extensions to test for parser desynchronization between the front-end proxy and aiohttp backend.
- Craft a request where a newline in a chunk extension causes the front end and backend to disagree about request boundaries.
- Embed a second HTTP request after the malformed chunked payload so that the backend processes it as a separate smuggled request.
- Use the smuggled request to attempt access to protected routes, bypass proxy/WAF rules, poison cacheable responses, or interfere with another request on the same connection.
- Repeat and tune payloads based on response timing, status codes, connection reuse behavior, and application-specific effects.
How to detect it
Historical exploitation is difficult to confirm because request smuggling payloads often rely on raw HTTP framing that many application logs do not preserve. Prioritize raw access logs from reverse proxies, WAFs, CDNs, API gateways, packet captures, load balancer logs, and aiohttp application logs around suspicious requests. Look for HTTP/1.1 requests using `Transfer-Encoding: chunked` with chunk extensions, malformed control characters, embedded newlines, unusual connection reuse patterns, unexpected backend-only route access, unexplained 400/408/502 responses, WAF/proxy parser errors, cache anomalies, and mismatches between front-end and backend request counts. Investigate cases where a front-end log shows one request but the backend logs show two requests on the same connection, or where backend access appears to bypass expected front-end authentication or routing rules. Also review deployment artifacts for exposure indicators such as `AIOHTTP_NO_EXTENSIONS` or aiohttp installations lacking compiled extensions, because those conditions increase relevance of this vulnerability.
- AIOHTTP_NO_EXTENSIONS
- Transfer-Encoding: chunked
- transfer-encoding: chunked
- Transfer-Encoding: Chunked
- BadHttpMessage
- BadStatusLine
- InvalidHeader
- aiohttp.http_exceptions
- chunk extension
- malformed chunked
- invalid chunk
- upstream sent invalid chunked response
- client sent invalid chunked body
- 400 Bad Request
- 408 Request Timeout
- 502 Bad Gateway
What your security team should do
- Inventory all services and containers using aiohttp and prioritize externally reachable HTTP services behind reverse proxies, WAFs, CDNs, API gateways, or load balancers.
- Upgrade affected deployments to aiohttp 3.10.11 or later, or to a build containing commit 3e09325e4839117df13fbac301f360edf8d3a0ee.
- Search runtime configuration for AIOHTTP_NO_EXTENSIONS and remove it unless explicitly required; if it must remain, treat the service as higher risk until upgraded.
- Add or confirm edge controls that reject malformed chunked transfer encoding, especially chunk extensions containing control characters or embedded newlines.
- Review proxy-to-backend HTTP/1.1 keep-alive and buffering settings for services where request smuggling would have high impact.
- Perform targeted request-smuggling testing in staging and, where safe, production validation using approved tooling and controlled payloads.
- Review recent HTTP logs and proxy error logs for malformed chunked requests, connection desynchronization symptoms, unexplained 400 responses, or anomalous access to backend-only paths.
- Ensure dependency scanning covers Python lockfiles, container images, and runtime environments, not only repository manifests.
The record
aiohttp is an asynchronous HTTP client/server framework for asyncio and Python. Prior to version 3.10.11, the Python parser parses newlines in chunk extensions incorrectly which can lead to request smuggling vulnerabilities under certain conditions. If a pure Python version of aiohttp is installed (i.e. without the usual C extensions) or `AIOHTTP_NO_EXTENSIONS` is enabled, then an attacker may be able to execute a request smuggling attack to bypass certain firewalls or proxy protections. Version 3.10.11 fixes the issue.
Affected packages
| Ecosystem | Package | Introduced | Fixed |
|---|---|---|---|
| PyPI | aiohttp | 0 | 3.10.11 |
| Chainguard | airflow | 0 | 2.10.3-r2 |
| Chainguard | airflow-bitnami-compat | 0 | 2.10.3-r2 |
| Chainguard | airflow-compat | 0 | 2.10.3-r2 |
| Chainguard | awx | 0 | 24.6.1-r2 |
| Chainguard | checkov | 0 | 3.2.432-r0 |
| Chainguard | dask-gateway | 0 | 2024.1.0-r11 |
| Chainguard | dask-gateway-server | 0 | 2024.1.0-r11 |
| Chainguard | kserve | 0 | 0.14.0-r0 |
| Chainguard | kserve-agent | 0 | 0.14.0-r0 |
| Chainguard | kserve-agent-compat | 0 | 0.14.0-r0 |
| Chainguard | kserve-manager | 0 | 0.14.0-r0 |
| Chainguard | kserve-manager-compat | 0 | 0.14.0-r0 |
| Chainguard | kserve-qpext | 0 | 0.14.0-r0 |
| Chainguard | kserve-qpext-compat | 0 | 0.14.0-r0 |
| Chainguard | kserve-router | 0 | 0.14.0-r0 |
| Chainguard | kserve-router-compat | 0 | 0.14.0-r0 |
| Chainguard | kserve-storage-controller | 0 | 0.14.0-r0 |
| Chainguard | py3-aiohttp | 0 | 3.10.11-r0 |
| Chainguard | py3-cassandra-medusa | 0 | 0.22.3-r1 |
| Chainguard | py3-cassandra-medusa-compat | 0 | 0.22.3-r1 |
| Chainguard | py3-supported-aiohttp | 0 | 3.10.11-r0 |
| Chainguard | py3.10-aiohttp | 0 | 3.10.11-r0 |
| Chainguard | py3.10-vllm-cuda-11.8 | 0 | 0.6.5-r1 |
| Chainguard | py3.10-wheels-vllm-cuda-11.8 | 0 | 0.6.5-r1 |
| Chainguard | py3.11-aiohttp | 0 | 3.10.11-r0 |
| Chainguard | py3.12-aiohttp | 0 | 3.10.11-r0 |
| Chainguard | py3.13-aiohttp | 0 | 3.10.11-r0 |
| Chainguard | request-1276 | 0 | 0.22.3-r1 |
| Chainguard | request-1276-compat | 0 | 0.22.3-r1 |
| Debian:11 | python-aiohttp | 0 | No fix |
| Debian:11 | python-aiohttp | 0 | 3.7.4-1+deb11u1 |
| Debian:12 | python-aiohttp | 0 | No fix |
| Debian:12 | python-aiohttp | 0 | 3.8.4-1+deb12u1 |
| Debian:13 | python-aiohttp | 0 | No fix |
| Debian:14 | python-aiohttp | 0 | 3.10.11-1 |
| Mageia:9 | python-aiohttp | 0 | 3.8.3-3.2.mga9 |
| Red Hat:ansible_automation_platform:2.5::el8 | automation-controller-venv-tower | 0 | 0:4.6.3-1.el8ap |
| Red Hat:ansible_automation_platform:2.5::el8 | automation-controller-venv-tower | 0 | 0:4.6.6-1.el8ap |
| Red Hat:ansible_automation_platform:2.5::el8 | automation-gateway-server | 0 | 0:2.5.20250115-1.el8ap |
| Red Hat:ansible_automation_platform:2.5::el8 | python3.11-aiohttp | 0 | 0:3.10.11-1.el8ap |
| Red Hat:ansible_automation_platform:2.5::el8 | python3.11-aiohttp-debuginfo | 0 | 0:3.10.11-1.el8ap |
| Red Hat:ansible_automation_platform:2.5::el8 | python3.11-aiohttp-debugsource | 0 | 0:3.10.11-1.el8ap |
| Red Hat:ansible_automation_platform:2.5::el8 | receptor | 0 | 0:1.5.1-2.el8ap |
| Red Hat:ansible_automation_platform:2.5::el8 | receptor-debuginfo | 0 | 0:1.5.1-2.el8ap |
| Red Hat:ansible_automation_platform:2.5::el8 | receptor-debugsource | 0 | 0:1.5.1-2.el8ap |
| Red Hat:ansible_automation_platform:2.5::el8 | receptorctl | 0 | 0:1.5.1-2.el8ap |
| Red Hat:ansible_automation_platform:2.5::el9 | automation-controller-venv-tower | 0 | 0:4.6.3-1.el9ap |
| Red Hat:ansible_automation_platform:2.5::el9 | automation-controller-venv-tower | 0 | 0:4.6.6-1.el9ap |
| Red Hat:ansible_automation_platform:2.5::el9 | automation-gateway-server | 0 | 0:2.5.20250115-1.el9ap |
| Red Hat:ansible_automation_platform:2.5::el9 | python3.11-aiohttp | 0 | 0:3.10.11-1.el9ap |
| Red Hat:ansible_automation_platform:2.5::el9 | python3.11-aiohttp-debuginfo | 0 | 0:3.10.11-1.el9ap |
| Red Hat:ansible_automation_platform:2.5::el9 | python3.11-aiohttp-debugsource | 0 | 0:3.10.11-1.el9ap |
| Red Hat:ansible_automation_platform:2.5::el9 | receptor | 0 | 0:1.5.1-2.el9ap |
| Red Hat:ansible_automation_platform:2.5::el9 | receptor-debuginfo | 0 | 0:1.5.1-2.el9ap |
| Red Hat:ansible_automation_platform:2.5::el9 | receptor-debugsource | 0 | 0:1.5.1-2.el9ap |
| Red Hat:ansible_automation_platform:2.5::el9 | receptorctl | 0 | 0:1.5.1-2.el9ap |
| Red Hat:ansible_automation_platform_developer:2.5::el8 | automation-controller-venv-tower | 0 | 0:4.6.3-1.el8ap |
| Red Hat:ansible_automation_platform_developer:2.5::el8 | automation-controller-venv-tower | 0 | 0:4.6.6-1.el8ap |
| Red Hat:ansible_automation_platform_developer:2.5::el8 | receptor | 0 | 0:1.5.1-2.el8ap |
| Red Hat:ansible_automation_platform_developer:2.5::el8 | receptor-debuginfo | 0 | 0:1.5.1-2.el8ap |
| Red Hat:ansible_automation_platform_developer:2.5::el8 | receptor-debugsource | 0 | 0:1.5.1-2.el8ap |
| Red Hat:ansible_automation_platform_developer:2.5::el8 | receptorctl | 0 | 0:1.5.1-2.el8ap |
| Red Hat:ansible_automation_platform_developer:2.5::el9 | automation-controller-venv-tower | 0 | 0:4.6.3-1.el9ap |
| Red Hat:ansible_automation_platform_developer:2.5::el9 | automation-controller-venv-tower | 0 | 0:4.6.6-1.el9ap |
| Red Hat:ansible_automation_platform_developer:2.5::el9 | receptor | 0 | 0:1.5.1-2.el9ap |
| Red Hat:ansible_automation_platform_developer:2.5::el9 | receptor-debuginfo | 0 | 0:1.5.1-2.el9ap |
| Red Hat:ansible_automation_platform_developer:2.5::el9 | receptor-debugsource | 0 | 0:1.5.1-2.el9ap |
| Red Hat:ansible_automation_platform_developer:2.5::el9 | receptorctl | 0 | 0:1.5.1-2.el9ap |
| Red Hat:ansible_automation_platform_inside:2.5::el8 | receptor | 0 | 0:1.5.1-2.el8ap |
| Red Hat:ansible_automation_platform_inside:2.5::el8 | receptor-debuginfo | 0 | 0:1.5.1-2.el8ap |
| Red Hat:ansible_automation_platform_inside:2.5::el8 | receptor-debugsource | 0 | 0:1.5.1-2.el8ap |
| Red Hat:ansible_automation_platform_inside:2.5::el8 | receptorctl | 0 | 0:1.5.1-2.el8ap |
| Red Hat:ansible_automation_platform_inside:2.5::el9 | receptor | 0 | 0:1.5.1-2.el9ap |
| Red Hat:ansible_automation_platform_inside:2.5::el9 | receptor-debuginfo | 0 | 0:1.5.1-2.el9ap |
| Red Hat:ansible_automation_platform_inside:2.5::el9 | receptor-debugsource | 0 | 0:1.5.1-2.el9ap |
| Red Hat:ansible_automation_platform_inside:2.5::el9 | receptorctl | 0 | 0:1.5.1-2.el9ap |
| Red Hat:satellite:6.16::el8 | python-aiohttp | 0 | 0:3.10.11-1.el8pc |
| Red Hat:satellite:6.16::el8 | python-aiohttp-debugsource | 0 | 0:3.10.11-1.el8pc |
| Red Hat:satellite:6.16::el8 | python3.11-aiohttp | 0 | 0:3.10.11-1.el8pc |
| Red Hat:satellite:6.16::el8 | python3.11-aiohttp-debuginfo | 0 | 0:3.10.11-1.el8pc |
| Red Hat:satellite:6.16::el9 | python-aiohttp | 0 | 0:3.10.11-1.el9pc |
| Red Hat:satellite:6.16::el9 | python-aiohttp-debugsource | 0 | 0:3.10.11-1.el9pc |
| Red Hat:satellite:6.16::el9 | python3.11-aiohttp | 0 | 0:3.10.11-1.el9pc |
| Red Hat:satellite:6.16::el9 | python3.11-aiohttp-debuginfo | 0 | 0:3.10.11-1.el9pc |
| Red Hat:satellite_capsule:6.16::el8 | python-aiohttp | 0 | 0:3.10.11-1.el8pc |
| Red Hat:satellite_capsule:6.16::el8 | python-aiohttp-debugsource | 0 | 0:3.10.11-1.el8pc |
| Red Hat:satellite_capsule:6.16::el8 | python3.11-aiohttp | 0 | 0:3.10.11-1.el8pc |
| Red Hat:satellite_capsule:6.16::el8 | python3.11-aiohttp-debuginfo | 0 | 0:3.10.11-1.el8pc |
| Red Hat:satellite_capsule:6.16::el9 | python-aiohttp | 0 | 0:3.10.11-1.el9pc |
| Red Hat:satellite_capsule:6.16::el9 | python-aiohttp-debugsource | 0 | 0:3.10.11-1.el9pc |
| Red Hat:satellite_capsule:6.16::el9 | python3.11-aiohttp | 0 | 0:3.10.11-1.el9pc |
| Red Hat:satellite_capsule:6.16::el9 | python3.11-aiohttp-debuginfo | 0 | 0:3.10.11-1.el9pc |
| SUSE:Linux Enterprise Module for Public Cloud 15 SP2 | python-aiohttp | 0 | 3.6.0-150100.3.18.1 |
| SUSE:Linux Enterprise Module for Public Cloud 15 SP3 | python-aiohttp | 0 | 3.6.0-150100.3.18.1 |
| SUSE:Linux Enterprise Module for Public Cloud 15 SP4 | python-aiohttp | 0 | 3.9.3-150400.10.27.1 |
| SUSE:Linux Enterprise Module for Public Cloud 15 SP4 | python-aiohttp | 0 | 3.6.0-150100.3.18.1 |
| SUSE:Linux Enterprise Module for Public Cloud 15 SP5 | python-aiohttp | 0 | 3.6.0-150100.3.18.1 |
| SUSE:Linux Enterprise Module for Public Cloud 15 SP6 | python-aiohttp | 0 | 3.6.0-150100.3.18.1 |
| SUSE:Linux Enterprise Module for Python 3 15 SP5 | python-aiohttp | 0 | 3.9.3-150400.10.27.1 |
| SUSE:Linux Enterprise Module for Python 3 15 SP6 | python-aiohttp | 0 | 3.9.3-150400.10.27.1 |
| Ubuntu:20.04:LTS | python-aiohttp | 0 | No fix |
| Ubuntu:22.04:LTS | python-aiohttp | 0 | No fix |
| Ubuntu:24.04:LTS | python-aiohttp | 0 | No fix |
| Ubuntu:24.10 | python-aiohttp | 0 | No fix |
| Ubuntu:Pro:16.04:LTS | python-aiohttp | 0 | No fix |
| Ubuntu:Pro:18.04:LTS | python-aiohttp | 0 | No fix |
| Ubuntu:Pro:18.04:LTS | python-aiohttp | 0 | 3.0.1-1ubuntu0.1~esm5 |
| Ubuntu:Pro:22.04:LTS | python-aiohttp | 0 | 3.8.1-4ubuntu0.2+esm1 |
| Ubuntu:Pro:24.04:LTS | python-aiohttp | 0 | 3.9.1-1ubuntu0.1+esm1 |
| Wolfi | airflow | 0 | 2.10.3-r2 |
| Wolfi | airflow-bitnami-compat | 0 | 2.10.3-r2 |
| Wolfi | airflow-compat | 0 | 2.10.3-r2 |
| Wolfi | checkov | 0 | 3.2.432-r0 |
| Wolfi | dask-gateway | 0 | 2024.1.0-r11 |
| Wolfi | dask-gateway-server | 0 | 2024.1.0-r11 |
| Wolfi | kserve | 0 | 0.14.0-r0 |
| Wolfi | kserve-agent | 0 | 0.14.0-r0 |
| Wolfi | kserve-agent-compat | 0 | 0.14.0-r0 |
| Wolfi | kserve-manager | 0 | 0.14.0-r0 |
| Wolfi | kserve-manager-compat | 0 | 0.14.0-r0 |
| Wolfi | kserve-qpext | 0 | 0.14.0-r0 |
| Wolfi | kserve-qpext-compat | 0 | 0.14.0-r0 |
| Wolfi | kserve-router | 0 | 0.14.0-r0 |
| Wolfi | kserve-router-compat | 0 | 0.14.0-r0 |
| Wolfi | kserve-storage-controller | 0 | 0.14.0-r0 |
| Wolfi | py3-aiohttp | 0 | 3.10.11-r0 |
| Wolfi | py3-cassandra-medusa | 0 | 0.22.3-r1 |
| Wolfi | py3-cassandra-medusa-compat | 0 | 0.22.3-r1 |
| Wolfi | py3-supported-aiohttp | 0 | 3.10.11-r0 |
| Wolfi | py3.10-aiohttp | 0 | 3.10.11-r0 |
| Wolfi | py3.11-aiohttp | 0 | 3.10.11-r0 |
| Wolfi | py3.12-aiohttp | 0 | 3.10.11-r0 |
| Wolfi | py3.13-aiohttp | 0 | 3.10.11-r0 |
| openSUSE:Leap 15.5 | python-aiohttp | 0 | 3.9.3-150400.10.27.1 |
| openSUSE:Leap 15.5 | python-aiohttp | 0 | 3.6.0-150100.3.18.1 |
| openSUSE:Leap 15.6 | python-aiohttp | 0 | 3.9.3-150400.10.27.1 |
Related vulnerabilities
- CVE-2025-69229 AIOHTTP is an asynchronous HTTP client/server framework for asyncio and Python. Also affects aiohttp
- CVE-2025-69223 AIOHTTP's HTTP Parser auto_decompress feature is vulnerable to zip bomb Also affects aiohttp
- CVE-2025-69224 AIOHTTP's unicode processing of header values could cause parsing discrepancies Also affects aiohttp
- CVE-2025-69226 AIOHTTP vulnerable to brute-force leak of internal static file path components Also affects aiohttp
- CVE-2025-69225 AIOHTTP has unicode match groups in regexes for ASCII protocol elements Also affects aiohttp
- CVE-2025-69228 AIOHTTP vulnerable to denial of service through large payloads Also affects aiohttp
- CVE-2025-69230 AIOHTTP Vulnerable to Cookie Parser Warning Storm Also affects aiohttp
- CVE-2025-69227 AIOHTTP vulnerable to DoS when bypassing asserts Also affects aiohttp