CVE-2025-69226
Medium · 5.3AIOHTTP vulnerable to brute-force leak of internal static file path components
CVSS
5.3
EPSS
0.4%
Published
Jan 5, 2026
CISA due date
—
Cloudanix analysis
A website component could let outsiders check whether certain server folders or files exist, helping them plan more targeted attacks.
- Exploitation
- Remote Unauthenticated
- Attacker needs
- None
- Complexity
- Moderate
- Impact
- Data Exposure
- Component
- Web Framework
- Class
- Path Traversal
- Remediation
- Upgrade
- Effort
- Medium
- Patch risk
- Low
What it actually does
The flaw is a path handling issue in static file serving: normalization prevents direct path traversal and file disclosure, but differences in request handling and responses can allow a remote attacker to infer whether absolute filesystem path components exist on the server. Technically, this creates a filesystem existence oracle rather than full arbitrary file read. An attacker may be able to enumerate directory or file path names, learn deployment layout, identify installed software locations, or validate targets for later attacks.
Why it matters to the business
The direct impact is moderate because the issue does not appear to provide immediate code execution or direct file contents disclosure, and it is not currently listed in CISA KEV, ransomware use, or known mature exploitation. However, exposing filesystem structure can still aid targeted intrusion, improve follow-on exploit reliability, and leak operational details about application deployments. Internet-facing services that serve static files through affected aiohttp-derived code or affected downstream packages should be prioritized, especially because the issue has been public for an extended period.
How an attack unfolds
An attacker sends crafted HTTP requests to a static-file route using absolute-path-like or encoded path components. Although normal traversal protections prevent retrieving files outside the configured static directory, the vulnerable normalization behavior can produce distinguishable responses depending on whether portions of the absolute path exist on the underlying filesystem. By repeating requests for common paths, application directories, user home directories, configuration locations, container mount points, or package paths, the attacker can build a map of the host filesystem. That information can then be used to refine phishing, choose exploit payload paths, identify secrets locations, or support later vulnerabilities that require a valid local path.
How to fix it
Upgrade affected packages to fixed versions or later. For the listed Debian packages, ensure Debian 11 systems are updated to a package containing the fix identified as 5.10.113-1 or later, and Debian 12 and Debian 13 systems are updated to 5.17.3-1 or later where applicable. For aio-libs/aiohttp source builds, update to a version containing commit 41f01ed680b7efc8f97677df45731b80328aad6c or a later official release that includes the fix. Rebuild and redeploy applications that vendor, pin, or bundle aiohttp. If immediate patching is not possible, restrict direct internet exposure of affected static routes, serve static files through a hardened reverse proxy or object store, normalize and reject absolute-path-like input before it reaches the application, block encoded traversal probes at the edge, and ensure error responses for invalid paths are uniform and do not reveal path existence.
How to confirm the fix worked
Confirm package and dependency versions on all systems and application images, including transitive or vendored aiohttp copies. For Debian-based systems, verify installed package versions with the package manager and confirm they are at or above the fixed versions. For Python applications, inspect lockfiles, runtime environments, container images, and software bills of materials for aiohttp versions or source commits containing the fix. Functionally validate by sending controlled requests with absolute-path-like and encoded path components to static routes and confirming responses are uniform for existing and non-existing absolute paths. Also verify that reverse proxies or WAF rules do not allow encoded variants to bypass normalization controls.
Typical attack path
- Identify an HTTP service using affected static file serving behavior, commonly an aiohttp-based application or downstream packaged version.
- Find a static asset route that accepts user-controlled path components.
- Send benign baseline requests for valid and invalid static paths to understand normal status codes, redirects, errors, timing, and response sizes.
- Send crafted requests containing absolute-path-like, traversal-like, or URL-encoded path components.
- Compare status codes, response bodies, redirects, error messages, and timing to infer whether tested absolute path components exist.
- Automate enumeration of common filesystem paths such as application directories, user directories, configuration paths, virtual environment paths, and container mount points.
- Use the discovered filesystem layout to support subsequent attacks, such as targeted exploit attempts, local path guessing, or sensitive-file location discovery through another weakness.
How to detect it
Review HTTP access logs, application logs, reverse proxy logs, CDN logs, and WAF events for repeated requests to static file endpoints containing traversal-like, absolute-path-like, or encoded path payloads. Look for bursts of 400, 403, 404, or 500 responses with small response-size differences, repeated probes for common Unix paths, and sequential testing of path prefixes. Compare requests from the same source IP, user agent, session, or ASN that enumerate many candidate paths. Because this issue primarily leaks path existence rather than writing files or executing commands, host artifacts may be minimal; focus on web logs and any application debug/error logs that record normalized paths or filesystem lookup failures. If suspicious probing is identified, correlate with subsequent requests from the same actor attempting to access discovered application paths, configuration endpoints, backup files, admin routes, or unrelated vulnerabilities.
- ../
- ..%2f
- %2e%2e%2f
- %252e%252e%252f
- ..%5c
- %2e%2e%5c
- /etc/passwd
- /etc/shadow
- /proc/self/environ
- /proc/self/cmdline
- /proc/1/environ
- /var/www
- /var/www/html
- /var/log
- /app
- /srv
- /home/
- /root/
- /usr/local/
- /opt/
- /static//etc/
- /static/%2fetc%2f
- /static/..%2f
- /static/%2e%2e%2f
- /static/%252e%252e%252f
What your security team should do
- Inventory internet-facing and internal web applications that use aiohttp or affected downstream packages for static file serving.
- Patch or redeploy affected services to fixed versions, prioritizing externally reachable applications and services with sensitive deployment layouts.
- Search application, reverse proxy, CDN, and WAF logs for path probing patterns against static asset routes over at least the period since publication, with emphasis on repeated enumeration attempts.
- Add temporary edge filtering for absolute-path-like and encoded traversal payloads targeting static file routes until all services are confirmed fixed.
- Review error handling so invalid static-file requests return generic, consistent responses without path details.
- Update dependency scanning and SBOM processes to detect vendored or source-built aiohttp instances, not only package-manager installations.
- If suspicious enumeration is found, expand investigation to follow-on activity from the same source IPs, user agents, sessions, or authentication contexts.
The record
Path normalization for static files prevents path traversal, but opens up the ability for an attacker to ascertain the existence of absolute path components.
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-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-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