CVE-2025-71351 Overview
CVE-2025-71351 is a detection bypass vulnerability in picklescan versions before 0.0.25. The tool fails to flag malicious pickle files that invoke timeit.timeit() inside the __reduce__ method. Attackers craft pickle payloads that import dangerous modules such as os and execute arbitrary system commands. The malicious code runs when an application calls pickle.load() on the file. Because picklescan is widely used to validate machine learning model artifacts before loading, this gap exposes ML pipelines to remote code execution through untrusted model files.
Critical Impact
Attackers can deliver weaponized pickle files that evade picklescan scanning and execute arbitrary commands on systems that load the file.
Affected Products
- picklescan versions prior to 0.0.25
- Machine learning pipelines that rely on picklescan to validate model files
- Applications loading pickle artifacts from public model repositories
Discovery Timeline
- 2026-06-21 - CVE-2025-71351 published to NVD
- 2026-06-22 - Last updated in NVD database
Technical Details for CVE-2025-71351
Vulnerability Analysis
The vulnerability sits in the static analysis logic of picklescan, which inspects pickle bytecode to identify dangerous imports and callables before deserialization. The scanner maintains an allowlist and denylist of modules and functions associated with code execution. The timeit.timeit() function accepts a string of Python code and executes it through exec(), but the scanner does not classify timeit as a dangerous module. Attackers exploit this oversight by chaining timeit.timeit() with a code string that imports os and runs shell commands. The malicious pickle passes scanning yet executes attacker-controlled code on deserialization. This is an incomplete denylist weakness tracked as [CWE-184].
Root Cause
The root cause is an incomplete blocklist in picklescan. The scanner enumerates known execution sinks such as os.system, subprocess, and eval, but omits timeit.timeit. Because timeit.timeit() evaluates arbitrary Python source strings, it functions as an indirect exec() primitive that the scanner does not recognize.
Attack Vector
An attacker publishes or shares a pickle file containing a class whose __reduce__ method returns a call to timeit.timeit with a payload string. The payload imports os and executes commands such as reverse shells or credential exfiltration. A victim runs picklescan against the file, receives a clean result, then calls pickle.load() to deserialize the object. Deserialization triggers __reduce__, which runs timeit.timeit() and executes the embedded code under the victim's process context.
No verified proof-of-concept code is published for this advisory. See the GitHub Security Advisory and the VulnCheck Advisory for additional technical context.
Detection Methods for CVE-2025-71351
Indicators of Compromise
- Pickle files that reference the timeit module in their opcode stream, particularly GLOBAL opcodes naming timeit timeit.
- Unexpected child processes spawned by Python interpreters shortly after model or pickle file loads.
- Outbound network connections from ML training or inference workloads to unknown hosts immediately following pickle.load() calls.
Detection Strategies
- Inspect pickle files with pickletools.dis() and flag any reference to timeit, pdb, bdb, runpy, or other indirect execution modules in addition to the standard denylist.
- Monitor process trees for Python processes that fork shells (sh, bash, cmd.exe, powershell.exe) during model loading workflows.
- Apply file integrity monitoring to model directories and alert on unsigned or externally sourced pickle artifacts.
Monitoring Recommendations
- Log every invocation of pickle.load() and torch.load() in production code paths and correlate with downstream process and network activity.
- Track picklescan versions across CI/CD systems and developer workstations to confirm upgrades to 0.0.25 or later.
- Alert on machine learning hosts that initiate outbound connections outside known registry and dataset endpoints.
How to Mitigate CVE-2025-71351
Immediate Actions Required
- Upgrade picklescan to version 0.0.25 or later across all developer, build, and production environments.
- Re-scan pickle artifacts ingested before the upgrade with the patched scanner version.
- Treat any pickle file from an external or untrusted source as executable code and quarantine it until reviewed.
Patch Information
The maintainer addressed the issue in picklescan0.0.25 by extending the dangerous globals list to cover timeit.timeit and related execution primitives. Details are documented in the GitHub Security Advisory GHSA-v7x6-rv5q-mhwc.
Workarounds
- Avoid pickle.load() on untrusted input entirely and migrate to safer serialization formats such as safetensors for ML model weights.
- Execute pickle deserialization inside sandboxed containers with no network egress and restricted file system access.
- Maintain an internal allowlist of approved model hashes and reject any pickle file not matching the allowlist.
# Upgrade picklescan to the patched release
pip install --upgrade 'picklescan>=0.0.25'
picklescan --version
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

