CVE-2025-71355: Picklescan: NumPy gadget bypass enables pickle RCE
UNKNOWN PoC AVAILABLE CISA: ATTENDPicklescan is the static scanner many MLOps pipelines run before trusting a third-party pickle-based model file, and this flaw shows it fails to flag a NumPy gadget — numpy.testing._private.utils.runstring invoked from a crafted __reduce__ method — that imports os and executes arbitrary commands the moment the file is deserialized. The real danger isn't the exploit's sophistication, it's the false sense of security: teams that gate model ingestion on "picklescan says clean" get a rubber stamp instead of an actual guarantee, so a malicious model uploaded to a public hub or shared internally can sail through the exact check meant to catch it. Current exploitation signals are muted — EPSS sits at just 0.55% (top 58th percentile), there is no public PoC, no Nuclei template, and it is absent from CISA KEV — so this is not an active-exploitation emergency, but the blast radius is anywhere pickle-format models (legacy scikit-learn artifacts, some Hugging Face models) are ingested from untrusted or semi-trusted sources. Action: upgrade picklescan to >=0.0.25 immediately, and stop treating picklescan as a security boundary rather than a defense-in-depth layer — prefer safetensors for model distribution, sandbox any deserialization of externally-sourced pickle files, and retroactively audit recently ingested models for reduce-based gadgets using fickling or manual review as a compensating control.
What is the risk?
Low current exploitation likelihood (EPSS 0.55%, no KEV listing, no public exploit or scanner template) but high potential impact — successful exploitation yields arbitrary OS command execution, i.e. full compromise of whatever host loads the malicious pickle. The elevated concern is architectural: this is a bypass of a security control itself (picklescan), so organizations relying on it for a false sense of safety carry residual risk they may not be tracking. CWE-184 (incomplete blocklist) is a structural weakness class — new bypass variants targeting other stdlib/NumPy functions are plausible until picklescan moves to an allowlist model.
How does the attack unfold?
What systems are affected?
| Package | Ecosystem | Vulnerable Range | Patched |
|---|---|---|---|
| picklescan | pip | — | No patch |
Do you use picklescan? You're affected.
How severe is it?
What should I do?
1 step-
1) Upgrade picklescan to >=0.0.25 where the NumPy gadget is detected. 2) Do not rely on picklescan alone as a security boundary for untrusted pickle files — treat it as one layer in defense-in-depth. 3) Where possible, migrate model storage/distribution to safetensors or other non-executable serialization formats. 4) Sandbox or containerize (with no network/file-system access) any process that deserializes pickle files from external or unverified sources. 5) Detection: audit ingestion logs for pickle files containing numpy.testing._private.utils.runstring or other reduce-invoked stdlib calls; add allowlist-based scanning rules rather than relying solely on blocklists.
What does CISA's SSVC say?
Source: CISA Vulnrichment (SSVC v2.0). Decision based on the CISA Coordinator decision tree.
How is it classified?
Which compliance frameworks are affected?
This CVE is relevant to:
Frequently Asked Questions
What is CVE-2025-71355?
Picklescan is the static scanner many MLOps pipelines run before trusting a third-party pickle-based model file, and this flaw shows it fails to flag a NumPy gadget — numpy.testing._private.utils.runstring invoked from a crafted __reduce__ method — that imports os and executes arbitrary commands the moment the file is deserialized. The real danger isn't the exploit's sophistication, it's the false sense of security: teams that gate model ingestion on "picklescan says clean" get a rubber stamp instead of an actual guarantee, so a malicious model uploaded to a public hub or shared internally can sail through the exact check meant to catch it. Current exploitation signals are muted — EPSS sits at just 0.55% (top 58th percentile), there is no public PoC, no Nuclei template, and it is absent from CISA KEV — so this is not an active-exploitation emergency, but the blast radius is anywhere pickle-format models (legacy scikit-learn artifacts, some Hugging Face models) are ingested from untrusted or semi-trusted sources. Action: upgrade picklescan to >=0.0.25 immediately, and stop treating picklescan as a security boundary rather than a defense-in-depth layer — prefer safetensors for model distribution, sandbox any deserialization of externally-sourced pickle files, and retroactively audit recently ingested models for reduce-based gadgets using fickling or manual review as a compensating control.
Is CVE-2025-71355 actively exploited?
Proof-of-concept exploit code is publicly available for CVE-2025-71355, increasing the risk of exploitation.
How to fix CVE-2025-71355?
1) Upgrade picklescan to >=0.0.25 where the NumPy gadget is detected. 2) Do not rely on picklescan alone as a security boundary for untrusted pickle files — treat it as one layer in defense-in-depth. 3) Where possible, migrate model storage/distribution to safetensors or other non-executable serialization formats. 4) Sandbox or containerize (with no network/file-system access) any process that deserializes pickle files from external or unverified sources. 5) Detection: audit ingestion logs for pickle files containing numpy.testing._private.utils.runstring or other reduce-invoked stdlib calls; add allowlist-based scanning rules rather than relying solely on blocklists.
What systems are affected by CVE-2025-71355?
This vulnerability affects the following AI/ML architecture patterns: model serving, training pipelines, AI supply chain / model distribution, MLOps ingestion pipelines.
What is the CVSS score for CVE-2025-71355?
No CVSS score has been assigned yet.
What is the AI security impact?
Affected AI Architectures
MITRE ATLAS Techniques
AML.T0010.001 AI Software AML.T0010.003 Model AML.T0011.000 Unsafe AI Artifacts AML.T0050 Command and Scripting Interpreter AML.T0074 Masquerading Compliance Controls Affected
What are the technical details?
Original Advisory
Picklescan before 0.0.25 fails to detect unsafe global functions in the Numpy library, allowing attackers to bypass static analysis and execute arbitrary code during deserialization. Attackers can craft malicious pickle files using numpy.testing._private.utils.runstring within the reduce method to import dangerous libraries like os and execute arbitrary OS commands when the pickle file is loaded.
Exploitation Scenario
An adversary crafts a malicious .pkl file — disguised as a legitimate scikit-learn or legacy ML model — whose __reduce__ method calls numpy.testing._private.utils.runstring to dynamically import the os module and embed an arbitrary shell command. The attacker publishes this file to a model-sharing platform, GitHub repo, or sends it directly to a target's ML team. The victim's ingestion pipeline runs picklescan as a pre-load safety check; because picklescan's blocklist doesn't recognize this NumPy code path, the file is reported clean. The victim then loads the model via pickle.load/torch.load in a training or inference environment, triggering the reduce method and handing the attacker command execution on that host.
Weaknesses (CWE)
CWE-184 — Incomplete List of Disallowed Inputs: The product implements a protection mechanism that relies on a list of inputs (or properties of inputs) that are not allowed by policy or otherwise require other action to neutralize before additional processing takes place, but the list is incomplete.
- [Implementation] Do not rely exclusively on detecting disallowed inputs. There are too many variants to encode a character, especially when different environments are used, so there is a high likelihood of missing some variants. Only use detection of disallowed inputs as a mechanism for detecting suspicious activity. Ensure that you are using other protection mechanisms that only identify "good" input - such as lists of allowed inputs - and ensure that you are properly encoding your outputs.
Source: MITRE CWE corpus.
References
Timeline
Related Vulnerabilities
CVE-2026-3490 10.0 picklescan: blocklist bypass enables full RCE
Same package: picklescan GHSA-vvpj-8cmc-gx39 10.0 picklescan: security flaw enables exploitation
Same package: picklescan GHSA-g38g-8gr9-h9xp 9.8 picklescan: Allowlist Bypass evades input filtering
Same package: picklescan CVE-2025-1945 9.8 picklescan: ZIP flag bypass enables RCE in PyTorch models
Same package: picklescan GHSA-7wx9-6375-f5wh 9.8 picklescan: Allowlist Bypass evades input filtering
Same package: picklescan