CVE-2025-69229
Medium · 5.3CVSS
5.3
EPSS
0.4%
Published
Jan 6, 2026
CISA due date
—
Cloudanix analysis
A flaw in a Python web server library can let someone slow down or temporarily knock offline affected websites and APIs by sending specially shaped requests.
- Exploitation
- Remote Unauthenticated
- Attacker needs
- None
- Complexity
- Low
- Impact
- Denial Of Service
- Component
- Library
- Class
- Denial of service
- Remediation
- Upgrade
- Effort
- Medium
- Patch risk
- Low
What it actually does
Aiohttp versions 3.13.2 and earlier can spend excessive blocking CPU time while processing HTTP request bodies encoded with a very large number of chunks. When an aiohttp server endpoint calls request.read(), maliciously fragmented chunked input can cause the event loop to be blocked for noticeable periods, preventing the process from servicing other concurrent requests. The flaw is remotely reachable over the network, requires no authentication or user interaction, and primarily affects service availability rather than confidentiality or integrity.
Why it matters to the business
Public or internally reachable services built on vulnerable aiohttp versions may experience degraded performance or denial of service if attackers send specially crafted chunked requests. Because aiohttp is commonly embedded in Python web services, APIs, automation tools, and service backends, exposure may exist indirectly through applications that depend on the library. The current EPSS score is low and the issue is not listed in CISA KEV, but the attack is low-complexity and can affect availability of internet-facing services, so externally exposed aiohttp applications should be prioritized for patching.
How an attack unfolds
An attacker identifies an HTTP endpoint implemented with aiohttp that accepts request bodies and uses request.read() to consume them. The attacker opens one or more HTTP connections and sends requests using Transfer-Encoding: chunked, deliberately splitting the body into an unusually large number of chunks. During request body processing, vulnerable aiohttp versions perform CPU-intensive work in a way that blocks the asyncio event loop. Even if each request only consumes a moderate amount of blocking CPU time, repeated or concurrent requests can prevent the server from handling legitimate traffic, causing slow responses, timeouts, elevated CPU utilization, and possible service unavailability.
How to fix it
Upgrade aiohttp to version 3.13.3 or later. For source builds tracking the upstream Git repository, include commit 41f01ed680b7efc8f97677df45731b80328aad6c or a later release containing that fix. Where using distribution packages, apply the vendor-provided fixed packages; the supplied package metadata lists Debian 11 fixed in 5.10.127-1 and Debian 12/Debian 13 fixed in 5.18.5-1, but application owners should also verify the installed Python aiohttp package itself is no longer version 3.13.2 or earlier. As compensating controls, enforce request body size limits, request timeout limits, connection concurrency limits, and reverse-proxy or WAF protections that reject or rate-limit requests with excessive chunk counts. Review application handlers and avoid unnecessary full-body request.read() calls on untrusted large bodies where streaming or bounded reads are possible.
How to confirm the fix worked
Confirm all deployed Python environments, containers, virtual environments, and build artifacts use aiohttp 3.13.3 or later by checking package manifests, lockfiles, SBOMs, and runtime package versions. For Debian-managed packages, verify the relevant vendor fixed package versions are installed. Exercise representative endpoints with benign chunked requests and confirm the service remains responsive under expected request volumes. Validate reverse proxies or ingress gateways enforce request body, header, timeout, and connection limits. Confirm no application image or dependency lockfile still pins aiohttp <= 3.13.2.
Typical attack path
- Identify an HTTP service or API implemented with vulnerable aiohttp versions 3.13.2 or earlier.
- Find an endpoint that accepts a request body and reads it using aiohttp request.read().
- Send HTTP requests with Transfer-Encoding: chunked and an abnormally high number of chunks.
- Repeat the requests or run them concurrently to amplify event-loop blocking and CPU consumption.
- Cause legitimate requests to slow down, queue, time out, or fail while the aiohttp worker is busy processing malicious chunked bodies.
How to detect it
Investigate whether affected aiohttp services experienced abnormal availability events after publication by correlating HTTP access logs, reverse-proxy logs, application logs, container metrics, and host telemetry. Focus on periods with high CPU usage in Python/aiohttp worker processes, elevated event-loop latency, increased request queueing, and spikes in client timeouts or gateway errors. In web and proxy logs, look for requests using Transfer-Encoding: chunked, especially repeated POST/PUT/PATCH requests with small or missing content lengths, unusually long processing times, high request counts from a small set of IPs, or repeated connections that end in 408, 499, 502, 503, or 504 responses. Application logs may not record individual chunk counts, so absence of explicit chunk details does not rule out exploitation. If packet captures, WAF logs, or load balancer request traces are available, inspect for chunked bodies made of a very large number of small chunks. No public named threat actors or ransomware campaigns are currently associated with this issue in the provided data.
- Transfer-Encoding: chunked
- transfer-encoding: chunked
- aiohttp
- request.read()
- HTTP 408
- HTTP 499
- HTTP 502
- HTTP 503
- HTTP 504
- python
What your security team should do
- Inventory internet-facing and business-critical Python services that use aiohttp, including transitive dependencies inside containers and virtual environments.
- Prioritize upgrades to aiohttp 3.13.3 or later for externally reachable services and any endpoint that accepts request bodies.
- Add or verify ingress controls for maximum request body size, request duration, idle timeout, and per-client rate limits.
- Search logs and telemetry for unusual spikes in chunked requests, long request durations, HTTP 408/499/502/503/504 responses, and CPU saturation on aiohttp workers.
- Add dependency scanning policies to flag aiohttp versions 3.13.2 and earlier in source repositories, container images, and SBOMs.
- Where immediate patching is not possible, place vulnerable services behind a reverse proxy or WAF that can normalize, limit, or reject excessive chunked transfer encoding.
The record
AIOHTTP is an asynchronous HTTP client/server framework for asyncio and Python. In versions 3.13.2 and below, handling of chunked messages can result in excessive blocking CPU usage when receiving a large number of chunks. If an application makes use of the request.read() method in an endpoint, it may be possible for an attacker to cause the server to spend a moderate amount of blocking CPU time (e.g. 1 second) while processing the request. This could potentially lead to DoS as the server would be unable to handle other requests during that time. This issue is fixed in version 3.13.3.
Affected packages
| Ecosystem | Package | Introduced | Fixed |
|---|---|---|---|
| PyPI | aiohttp | 0 | 3.13.3 |
| Chainguard | airflow-2 | 0 | 2.11.0-r19 |
| Chainguard | airflow-2-bitnami-compat | 0 | 2.11.0-r19 |
| Chainguard | airflow-2-compat | 0 | 2.11.0-r19 |
| Chainguard | airflow-2-iamguarded-compat | 0 | 2.11.0-r19 |
| Chainguard | airflow-3-compat | 0 | 3.1.5-r1 |
| Chainguard | airflow-3-iamguarded-compat | 0 | 3.1.5-r1 |
| Chainguard | airflow-core-2 | 0 | 2.11.0-r11 |
| Chainguard | airflow-core-2-compat | 0 | 2.11.0-r10 |
| Chainguard | airflow-core-2-oci-entrypoint | 0 | 2.11.0-r10 |
| Chainguard | apache-beam-python-3.11-sdk | 0 | 2.70.0-r1 |
| Chainguard | authentik | 0 | 2025.10.3-r3 |
| Chainguard | authentik-fips | 0 | 2025.10.3-r1 |
| Chainguard | authentik-go-server | 0 | 2025.10.3-r3 |
| Chainguard | authentik-go-server-fips | 0 | 2025.10.3-r0 |
| Chainguard | awx | 0 | 24.6.1-r23 |
| Chainguard | checkov | 0 | 3.2.499-r0 |
| Chainguard | dask-kubernetes | 0 | 2025.7.0-r4 |
| Chainguard | gitaly-config-18.5 | 0 | 18.5.5-r0 |
| Chainguard | gitaly-config-18.6 | 0 | 18.6.2-r0 |
| Chainguard | gitaly-config-18.7 | 0 | 18.7.0-r0 |
| Chainguard | gitlab-base-18.5 | 0 | 18.5.4-r0 |
| Chainguard | gitlab-base-18.6 | 0 | 18.6.3-r0 |
| Chainguard | gitlab-base-18.7 | 0 | 18.7.0-r0 |
| Chainguard | gitlab-base-fips-18.5 | 0 | 18.5.4-r1 |
| Chainguard | gitlab-base-fips-18.6 | 0 | 18.6.3-r0 |
| Chainguard | gitlab-base-fips-18.7 | 0 | 18.7.0-r0 |
| Chainguard | gitlab-certificates-18.5 | 0 | 18.5.4-r0 |
| Chainguard | gitlab-certificates-18.6 | 0 | 18.6.2-r0 |
| Chainguard | gitlab-certificates-18.7 | 0 | 18.7.0-r0 |
| Chainguard | gitlab-cfssl-self-sign-scripts-18.5 | 0 | 18.5.4-r0 |
| Chainguard | gitlab-cfssl-self-sign-scripts-18.6 | 0 | 18.6.2-r0 |
| Chainguard | gitlab-cfssl-self-sign-scripts-18.7 | 0 | 18.7.1-r0 |
| Chainguard | gitlab-cng-18.5 | 0 | 18.5.4-r0 |
| Chainguard | gitlab-cng-18.6 | 0 | 18.6.3-r0 |
| Chainguard | gitlab-cng-18.7 | 0 | 18.7.0-r0 |
| Chainguard | gitlab-cng-fips-18.5 | 0 | 18.5.4-r1 |
| Chainguard | gitlab-cng-fips-18.6 | 0 | 18.6.3-r0 |
| Chainguard | gitlab-cng-fips-18.7 | 0 | 18.7.1-r0 |
| Chainguard | gitlab-container-registry-18.5 | 0 | 18.5.4-r0 |
| Chainguard | gitlab-container-registry-18.6 | 0 | 18.6.2-r0 |
| Chainguard | gitlab-container-registry-18.7 | 0 | 18.7.0-r0 |
| Chainguard | gitlab-container-registry-fips-18.5 | 0 | 18.5.4-r1 |
| Chainguard | gitlab-container-registry-fips-18.6 | 0 | 18.6.2-r1 |
| Chainguard | gitlab-container-registry-fips-18.7 | 0 | 18.7.0-r0 |
| Chainguard | gitlab-container-registry-scripts-18.5 | 0 | 18.5.4-r0 |
| Chainguard | gitlab-container-registry-scripts-18.6 | 0 | 18.6.2-r0 |
| Chainguard | gitlab-container-registry-scripts-18.7 | 0 | 18.7.0-r0 |
| Chainguard | gitlab-exporter-18.5 | 0 | 18.5.4-r0 |
| Chainguard | gitlab-exporter-18.6 | 0 | 18.6.2-r0 |
| Chainguard | gitlab-exporter-18.7 | 0 | 18.7.0-r0 |
| Chainguard | gitlab-exporter-scripts-18.5 | 0 | 18.5.4-r0 |
| Chainguard | gitlab-exporter-scripts-18.6 | 0 | 18.6.2-r0 |
| Chainguard | gitlab-exporter-scripts-18.7 | 0 | 18.7.0-r0 |
| Chainguard | gitlab-gitaly-scripts-18.5 | 0 | 18.5.5-r0 |
| Chainguard | gitlab-gitaly-scripts-18.6 | 0 | 18.6.2-r0 |
| Chainguard | gitlab-gitaly-scripts-18.7 | 0 | 18.7.0-r0 |
| Chainguard | gitlab-logger-18.5 | 0 | 18.5.5-r0 |
| Chainguard | gitlab-logger-18.6 | 0 | 18.6.2-r0 |
| Chainguard | gitlab-logger-18.7 | 0 | 18.7.0-r0 |
| Chainguard | gitlab-logger-fips-18.5 | 0 | 18.5.4-r1 |
| Chainguard | gitlab-logger-fips-18.6 | 0 | 18.6.2-r1 |
| Chainguard | gitlab-logger-fips-18.7 | 0 | 18.7.0-r0 |
| Chainguard | gitlab-pages-scripts-18.5 | 0 | 18.5.5-r0 |
| Chainguard | gitlab-pages-scripts-18.6 | 0 | 18.6.2-r0 |
| Chainguard | gitlab-pages-scripts-18.7 | 0 | 18.7.0-r0 |
| Chainguard | gitlab-rails-scripts-18.5 | 0 | 18.5.5-r0 |
| Chainguard | gitlab-rails-scripts-18.6 | 0 | 18.6.3-r0 |
| Chainguard | gitlab-rails-scripts-18.7 | 0 | 18.7.1-r0 |
| Chainguard | gitlab-rails-scripts-fips-18.5 | 0 | 18.5.4-r1 |
| Chainguard | gitlab-rails-scripts-fips-18.6 | 0 | 18.6.2-r1 |
| Chainguard | gitlab-rails-scripts-fips-18.7 | 0 | 18.7.0-r0 |
| Chainguard | gitlab-shell-18.5 | 0 | 18.5.5-r0 |
| Chainguard | gitlab-shell-18.6 | 0 | 18.6.2-r0 |
| Chainguard | gitlab-shell-18.7 | 0 | 18.7.1-r0 |
| Chainguard | gitlab-shell-fips-18.5 | 0 | 18.5.4-r1 |
| Chainguard | gitlab-shell-fips-18.6 | 0 | 18.6.2-r1 |
| Chainguard | gitlab-shell-fips-18.7 | 0 | 18.7.1-r0 |
| Chainguard | gitlab-shell-scripts-18.5 | 0 | 18.5.5-r0 |
| Chainguard | gitlab-shell-scripts-18.6 | 0 | 18.6.2-r0 |
| Chainguard | gitlab-shell-scripts-18.7 | 0 | 18.7.0-r0 |
| Chainguard | gitlab-sidekiq-ce-18.5 | 0 | 18.5.4-r0 |
| Chainguard | gitlab-sidekiq-ce-18.6 | 0 | 18.6.2-r0 |
| Chainguard | gitlab-sidekiq-ce-18.7 | 0 | 18.7.0-r0 |
| Chainguard | gitlab-sidekiq-ce-fips-18.5 | 0 | 18.5.4-r1 |
| Chainguard | gitlab-sidekiq-ce-fips-18.6 | 0 | 18.6.2-r1 |
| Chainguard | gitlab-sidekiq-ce-fips-18.7 | 0 | 18.7.1-r0 |
| Chainguard | gitlab-toolbox-ce-18.5 | 0 | 18.5.5-r0 |
| Chainguard | gitlab-toolbox-ce-18.6 | 0 | 18.6.3-r0 |
| Chainguard | gitlab-toolbox-ce-18.7 | 0 | 18.7.1-r0 |
| Chainguard | gitlab-toolbox-ce-fips-18.5 | 0 | 18.5.5-r0 |
| Chainguard | gitlab-toolbox-ce-fips-18.6 | 0 | 18.6.3-r0 |
| Chainguard | gitlab-toolbox-ce-fips-18.7 | 0 | 18.7.1-r0 |
| Chainguard | gitlab-webservice-ce-18.5 | 0 | 18.5.5-r0 |
| Chainguard | gitlab-webservice-ce-18.6 | 0 | 18.6.2-r0 |
| Chainguard | gitlab-webservice-ce-18.7 | 0 | 18.7.0-r0 |
| Chainguard | gitlab-webservice-ce-fips-18.5 | 0 | 18.5.4-r1 |
| Chainguard | gitlab-webservice-ce-fips-18.6 | 0 | 18.6.3-r0 |
| Chainguard | gitlab-webservice-ce-fips-18.7 | 0 | 18.7.1-r0 |
| Chainguard | gitlab-workhorse-scripts-18.5 | 0 | 18.5.5-r0 |
| Chainguard | gitlab-workhorse-scripts-18.6 | 0 | 18.6.2-r0 |
| Chainguard | gitlab-workhorse-scripts-18.7 | 0 | 18.7.0-r0 |
| Chainguard | gitlab-workhorse-scripts-fips-18.5 | 0 | 18.5.4-r1 |
| Chainguard | gitlab-workhorse-scripts-fips-18.6 | 0 | 18.6.3-r0 |
| Chainguard | gitlab-workhorse-scripts-fips-18.7 | 0 | 18.7.0-r0 |
| Chainguard | kubeflow-pipelines-visualization-server | 0 | 2.15.0-r1 |
| Chainguard | open-webui | 0 | 0.6.43-r1 |
| Chainguard | open-webui-compat | 0 | 0.6.43-r0 |
| Chainguard | py3-cassandra-medusa | 0 | 0.26.0-r3 |
| Chainguard | py3-cassandra-medusa-compat | 0 | 0.26.0-r3 |
| Chainguard | py3-vllm-cuda-12.4 | 0 | 0.13.0-r1 |
| Chainguard | py3.10-vllm-cuda-12.4 | 0 | 0.16.0-r1 |
| Chainguard | py3.11-text-generation-inference | 0 | 3.3.7-r2 |
| Chainguard | py3.12-vllm-cuda-12.4 | 0 | 0.16.0-r1 |
| Chainguard | request-1276 | 0 | 0.27.0-r1 |
| Chainguard | request-1276-compat | 0 | 0.27.0-r1 |
| Chainguard | text-generation-inference | 0 | 3.3.7-r2 |
| Chainguard | text-generation-inference-compat | 0 | 3.3.7-r2 |
| Chainguard | tritonserver-backend-vllm-cuda-12.9 | 0 | 25.9.0_git20251112-r7 |
| Chainguard | tritonserver-backend-vllm-meta-cuda-12.9 | 0 | 25.9.0_git20251112-r4 |
| SUSE:Linux Enterprise High Performance Computing 15 SP4-ESPOS | python-aiohttp | 0 | 3.9.3-150400.10.36.1 |
| SUSE:Linux Enterprise High Performance Computing 15 SP4-LTSS | python-aiohttp | 0 | 3.9.3-150400.10.36.1 |
| SUSE:Linux Enterprise High Performance Computing 15 SP5-ESPOS | python-aiohttp | 0 | 3.9.3-150400.10.36.1 |
| SUSE:Linux Enterprise High Performance Computing 15 SP5-LTSS | python-aiohttp | 0 | 3.9.3-150400.10.36.1 |
| SUSE:Linux Enterprise Module for Public Cloud 15 SP4 | python-aiohttp | 0 | 3.9.3-150400.10.36.1 |
| SUSE:Linux Enterprise Module for Python 3 15 SP7 | python-aiohttp | 0 | 3.9.3-150400.10.36.1 |
| SUSE:Linux Enterprise Server 15 SP4-LTSS | python-aiohttp | 0 | 3.9.3-150400.10.36.1 |
| SUSE:Linux Enterprise Server 15 SP5-LTSS | python-aiohttp | 0 | 3.9.3-150400.10.36.1 |
| SUSE:Linux Enterprise Server 15 SP6-LTSS | python-aiohttp | 0 | 3.9.3-150400.10.36.1 |
| SUSE:Linux Enterprise Server for SAP Applications 15 SP4 | python-aiohttp | 0 | 3.9.3-150400.10.36.1 |
| SUSE:Linux Enterprise Server for SAP Applications 15 SP5 | python-aiohttp | 0 | 3.9.3-150400.10.36.1 |
| SUSE:Linux Enterprise Server for SAP Applications 15 SP6 | python-aiohttp | 0 | 3.9.3-150400.10.36.1 |
| Wolfi | airflow-3-compat | 0 | 3.1.5-r1 |
| Wolfi | airflow-3-iamguarded-compat | 0 | 3.1.5-r1 |
| Wolfi | checkov | 0 | 3.2.499-r0 |
| Wolfi | dask-kubernetes | 0 | 2025.7.0-r4 |
| Wolfi | kubeflow-pipelines-visualization-server | 0 | 2.15.0-r1 |
| Wolfi | open-webui | 0 | 0.6.43-r1 |
| Wolfi | open-webui-compat | 0 | 0.6.43-r0 |
| Wolfi | py3-cassandra-medusa | 0 | 0.26.0-r3 |
| Wolfi | py3-cassandra-medusa-compat | 0 | 0.26.0-r3 |
| openSUSE:Leap 15.6 | python-aiohttp | 0 | 3.9.3-150400.10.36.1 |
| openSUSE:Leap 16.0 | python-Brotli | 0 | 1.1.0-160000.3.1 |
| openSUSE:Leap 16.0 | python-aiohttp | 0 | 3.11.16-160000.3.1 |
| openSUSE:Tumbleweed | python-aiohttp | 0 | 3.13.3-1.1 |
Related vulnerabilities
- 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
- CVE-2025-53643 AIOHTTP is an asynchronous HTTP client/server framework for asyncio and Python. Also affects aiohttp