Cloudanix VulnDB

CVE-2026-25645

Medium · 4.4

CVSS

4.4

EPSS

0.2%

Published

Mar 25, 2026

CISA due date

—

Cloudanix analysis

Schedule a fix SSVC: Track

Some applications using an older Python web library could be tricked by a local user into reading a fake temporary file instead of the real one.

Exploitation
Local Privilege
Attacker needs
Local User
Complexity
High
Impact
Data Tampering
Component
Library
Class
Race Condition
Remediation
Upgrade
Effort
Medium
Patch risk
Low

What it actually does

This is a local file-substitution race condition in Python Requests before 2.33.0, limited to applications that directly call requests.utils.extract_zipped_paths(). The vulnerable helper extracts files from ZIP archives into the system temporary directory using a predictable destination path and reuses an existing file without validating that it was created from the expected archive content. A local attacker who can write to the same temporary directory can pre-create the expected extracted file so that the application later loads attacker-controlled content instead of the legitimate ZIP member. Standard HTTP client usage of Requests is not affected.

Why it matters to the business

Business risk is generally limited because exploitation requires local access, write permission to the temporary directory, and an application-specific code path that directly uses the vulnerable utility. Where affected, the impact can be significant: applications may process or trust attacker-supplied local content, potentially causing data corruption, incorrect business logic decisions, poisoned configuration or resource files, or further compromise depending on how the extracted file is used. The low EPSS score and absence from CISA KEV indicate no current evidence of broad exploitation, but organizations with Python applications that use this helper should still remediate during normal patch cycles.

How an attack unfolds

An attacker first obtains low-privileged local access on a system running a Python application that directly invokes requests.utils.extract_zipped_paths(). The attacker determines or predicts the temporary-file path that Requests will use when extracting a file from a ZIP archive. Before the application performs extraction, the attacker creates a malicious file at that predictable path in a shared temporary directory such as /tmp. When the application later calls the vulnerable helper, Requests sees the file already present and reuses it rather than validating or replacing it with the ZIP member. The application then consumes the attacker-controlled file as if it came from the trusted archive. The practical result depends on the application: the attacker may influence file parsing, load malicious data, poison caches, or alter application behavior.

How to fix it

Upgrade Python Requests to version 2.33.0 or later, where extraction uses a non-deterministic location. Because standard Requests HTTP usage is not affected, prioritize systems and applications that directly call requests.utils.extract_zipped_paths(). If immediate upgrade is not possible, set TMPDIR to a directory that is not world-writable and is writable only by the application user, and ensure equivalent controls are applied for other platform-specific temporary-directory environment variables where relevant. Review application code for direct use of extract_zipped_paths() and replace it with safer extraction logic where possible, including unique temporary directories, secure file creation, ownership validation, and cleanup.

How to confirm the fix worked

Confirm installed Requests versions by inspecting package inventories, virtual environments, containers, build manifests, and lockfiles; affected deployments use requests versions earlier than 2.33.0. Confirm whether the application directly imports or calls requests.utils.extract_zipped_paths(); systems that do not call this utility are not affected by the described issue. Validate remediation by verifying Requests 2.33.0 or later is installed in the runtime actually used by the application. For mitigated systems, confirm TMPDIR points to a restricted directory owned by the application user and not writable by other local users. A practical exposure test is to run the affected application path in a non-production test environment while monitoring whether extracted ZIP members are written to predictable names in a shared temporary directory or whether pre-existing files are reused.

Typical attack path

  1. Identify a Python application that uses Requests before version 2.33.0 and directly calls requests.utils.extract_zipped_paths().
  2. Gain local low-privileged access or another ability to write into the same system temporary directory used by the application.
  3. Predict the filename or path that the vulnerable helper will use for ZIP extraction.
  4. Pre-create a malicious file at that path before the target application performs extraction.
  5. Wait for or trigger the application code path that calls extract_zipped_paths().
  6. Cause the application to read or process the attacker-controlled file instead of the intended ZIP archive member.
  7. Leverage the application-specific handling of that file to alter behavior, corrupt data, or support further compromise.

How to detect it

There are no widely reported public exploitation patterns or known threat actors associated with this vulnerability, and it is not listed in CISA KEV. Detection should focus on exposure and local tampering evidence. Review application dependency inventories, SBOMs, virtual environments, and container images for Requests versions before 2.33.0. Search application source and deployed packages for direct use of requests.utils.extract_zipped_paths(). For possible exploitation, examine operating system audit logs, EDR file telemetry, and application logs for files created in shared temporary directories shortly before the affected application reads or extracts ZIP content. Look for temporary files owned by a different user than the application process, unexpected persistence of extracted files, permission anomalies, or repeated creation of the same predictable temporary path. On Linux, auditd or EDR events for open, creat, chmod, chown, and rename operations under /tmp, /var/tmp, or the configured TMPDIR can help reconstruct whether an unprivileged user pre-positioned files consumed by the application.

  • requests.utils.extract_zipped_paths
  • extract_zipped_paths(
  • from requests.utils import extract_zipped_paths
  • /tmp
  • /var/tmp
  • TMPDIR

What your security team should do

  • Inventory Python applications and containers using the requests package and identify versions earlier than 2.33.0.
  • Search source code and dependency usage for direct calls to requests.utils.extract_zipped_paths(); prioritize remediation only where that utility is used.
  • Upgrade affected environments to Requests 2.33.0 or later and rebuild/redeploy application images so the fixed library is present at runtime.
  • Where upgrade is delayed, set TMPDIR to an application-private directory with restrictive permissions and verify it is not shared or world-writable.
  • Review local-user threat models for multi-user servers, shared build systems, CI runners, batch workers, and application hosts where untrusted users or jobs can write to shared temporary directories.
  • Add code-review checks to discourage predictable temporary-file use and unsafe ZIP extraction patterns.
  • Monitor for suspicious pre-created files or ownership mismatches in temporary directories used by affected applications, especially around application execution times.

The record

Requests is a HTTP library. Prior to version 2.33.0, the `requests.utils.extract_zipped_paths()` utility function uses a predictable filename when extracting files from zip archives into the system temporary directory. If the target file already exists, it is reused without validation. A local attacker with write access to the temp directory could pre-create a malicious file that would be loaded in place of the legitimate one. Standard usage of the Requests library is not affected by this vulnerability. Only applications that call `extract_zipped_paths()` directly are impacted. Starting in version 2.33.0, the library extracts files to a non-deterministic location. If developers are unable to upgrade, they can set `TMPDIR` in their environment to a directory with restricted write access.

Affected packages

Ecosystem Package Introduced Fixed
Chainguard airflow-3 0 3.1.8-r10
Chainguard airflow-core-2 0 2.11.2-r3
Chainguard airflow-core-3 0 3.1.8-r3
Chainguard apache-beam-python-3.11-sdk 0 2.71.0-r8
Chainguard apache-beam-python-3.12-sdk 0 2.71.0-r2
Chainguard apache-beam-python-3.13-sdk 0 2.71.0-r2
Chainguard awx 0 24.6.1-r33
Chainguard az 0 2.84.0-r4
Chainguard barman-cloudnative-pg 0 3.18.0-r1
Chainguard checkov 0 3.2.511-r0
Chainguard confluent-docker-utils 0 0.0.169-r1
Chainguard dask-kubernetes 0 2026.3.0-r2
Chainguard datahub-ingestion 0 1.5.0.1-r0
Chainguard datahub-ingestion-fips 0 1.5.0.1-r0
Chainguard gitlab-toolbox-ce-18.9 0 18.9.3-r1
Chainguard gitlab-toolbox-ce-fips-18.9 0 18.9.3-r1
Chainguard jupyter-base-notebook 0 7.5.5-r1
Chainguard k8s-sidecar 0 2.5.1-r3
Chainguard keep-api 0 0.51.0-r2
Chainguard keep-api-fips 0 0.51.0-r2
Chainguard kserve-storage-controller 0 0.16.0-r24
Chainguard kubeflow-jupyter-web-app 0 1.10.0-r13
Chainguard kubeflow-pipelines-apiserver 0 2.16.0-r12
Chainguard kubeflow-volumes-web-app 0 1.10.0-r12
Chainguard label-studio 0 1.23.0-r1
Chainguard litellm 0 1.82.3.0-r2
Chainguard metaflow-service 0 2.5.0-r7
Chainguard metaflow-service-fips 0 2.5.0-r1
Chainguard mlflow 0 3.10.1-r1
Chainguard mlflow-iamguarded-compat 0 3.10.1-r1
Chainguard opal 0 0.9.4-r0
Chainguard opentelemetry-python-instrumentation 0 0.60.1-r3
Chainguard pgadmin4 0 9.13-r3
Chainguard pgadmin4-fips 0 9.13-r2
Chainguard py3.10-ambassador 0 3.10.0-r26
Chainguard py3.11-ambassador 0 3.10.0-r26
Chainguard py3.11-prefect 0 3.6.23-r0
Chainguard py3.11-prefect-fips 0 3.6.23-r0
Chainguard py3.12-ambassador 0 3.10.0-r26
Chainguard py3.12-prefect 0 3.6.23-r0
Chainguard py3.12-prefect-fips 0 3.6.23-r0
Chainguard py3.13-ambassador 0 3.10.0-r26
Chainguard py3.13-prefect 0 3.6.23-r0
Chainguard py3.13-prefect-fips 0 3.6.23-r0
Chainguard py3.14-prefect 0 3.6.23-r0
Chainguard semgrep 0 1.157.0-r1
Chainguard spamcheck 0 3.5.3-r8
Chainguard superset-5.0 0 5.0.0-r22
Chainguard superset-6.0 0 6.0.0-r7
Chainguard tritonserver-backend-vllm-cuda-12.9 0 25.9.0_git20260318-r0
Chainguard vllm-openai-cuda-12.9 0 0.17.1-r1
Chainguard wazuh-manager-framework 0 4.14.4-r1
Wolfi airflow-3 0 3.1.8-r10
Wolfi az 0 2.84.0-r4
Wolfi checkov 0 3.2.511-r0
Wolfi confluent-docker-utils 0 0.0.169-r1
Wolfi dask-kubernetes 0 2026.3.0-r2
Wolfi jupyter-base-notebook 0 7.5.5-r1
Wolfi k8s-sidecar 0 2.5.1-r3
Wolfi kserve-storage-controller 0 0.16.0-r24
Wolfi kubeflow-jupyter-web-app 0 1.10.0-r13
Wolfi kubeflow-pipelines-apiserver 0 2.16.0-r12
Wolfi kubeflow-volumes-web-app 0 1.10.0-r12
Wolfi mlflow 0 3.10.1-r1
Wolfi mlflow-iamguarded-compat 0 3.10.1-r1
Wolfi py3.10-ambassador 0 3.10.0-r26
Wolfi py3.11-ambassador 0 3.10.0-r26
Wolfi py3.12-ambassador 0 3.10.0-r26
Wolfi py3.13-ambassador 0 3.10.0-r26
Wolfi semgrep 0 1.157.0-r1
Wolfi superset-5.0 0 5.0.0-r22
Wolfi superset-6.0 0 6.0.0-r7
openSUSE:Leap 16.0 python-requests 0 2.32.4-160000.3.1
openSUSE:Tumbleweed python-requests 0 2.33.0-1.1

Related vulnerabilities