CVE-2025-71355: Picklescan: NumPy gadget bypass enables pickle RCE

UNKNOWN PoC AVAILABLE CISA: ATTEND
Published June 30, 2026
CISO Take

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.

Sources: NVD GitHub Advisory EPSS ATLAS

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?

Craft evasive payload
Adversary builds a malicious pickle file whose __reduce__ method calls numpy.testing._private.utils.runstring to bypass picklescan's blocklist-based detection.
AML.T0011.000
Distribute poisoned artifact
The malicious model/pickle file is published to a model hub, code repo, or sent directly to the target as a legitimate-looking ML artifact.
AML.T0010.003
Evade security scan
Victim's ingestion pipeline runs picklescan as a pre-load safety gate; the scan reports the file as clean due to the NumPy detection gap.
AML.T0074
Code execution on load
Victim deserializes the file via pickle.load/torch.load, triggering the reduce method which imports os and executes arbitrary commands, giving the attacker code execution on the ML host.
AML.T0050

What systems are affected?

Package Ecosystem Vulnerable Range Patched
picklescan pip No patch
418 3 dependents Pushed 25d ago 53% patched ~12d to patch Full package profile →

Do you use picklescan? You're affected.

How severe is it?

CVSS 3.1
N/A
EPSS
0.6%
chance of exploitation in 30 days
Higher than 44% of all CVEs
Exploitation Status
Exploit Available
Exploitation: MEDIUM
Sophistication
Moderate
Exploitation Confidence
medium
CISA SSVC: Public PoC
Public PoC indexed (trickest/cve)
Composite signal derived from CISA KEV, VulnCheck KEV, CISA SSVC, EPSS, Metasploit, Exploit-DB, trickest/cve, Nuclei templates, and inthewild.io exploitation reports.

What should I do?

1 step
  1. 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?

Decision Attend
Exploitation poc
Automatable Yes
Technical Impact total

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:

EU AI Act
Article 15 - Accuracy, robustness and cybersecurity
ISO 42001
A.6.2.3 / A.10 - Third-party and supply chain management
NIST AI RMF
MAP 3 / MANAGE 4 - Third-party AI component risk mapping and management
OWASP LLM Top 10
LLM03:2025 - Supply Chain Vulnerabilities

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

model servingtraining pipelinesAI supply chain / model distributionMLOps ingestion pipelines

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

EU AI Act: Article 15
ISO 42001: A.6.2.3 / A.10
NIST AI RMF: MAP 3 / MANAGE 4
OWASP LLM Top 10: LLM03:2025

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.

Timeline

Published
June 30, 2026
Last Modified
July 1, 2026
First Seen
June 30, 2026

Related Vulnerabilities