CVE-2026-14534: fickling: denylist gaps let malicious pickles execute

HIGH PoC AVAILABLE CISA: ATTEND
Published July 4, 2026
CISO Take

Fickling is Trail of Bits' security gate meant to block malicious pickle files before they're deserialized, but its denylist omits three standard-library modules — _posixsubprocess, site, and atexit — that a crafted pickle can invoke to spawn arbitrary processes, run injected code, or trigger callback execution, and check_safety() waves the payload through as LIKELY_SAFE with zero findings. This matters because any pipeline that trusts fickling.load() as a gatekeeper before loading a downloaded model checkpoint or dataset pickle now has a false sense of security — a poisoned .pkl or .pt file disguised as a legitimate model can achieve full remote code execution the moment it's loaded, and the CVSS 8.8 score (AV:N/AC:L/PR:N) reflects how low the bar is once a victim is convinced to open the file. There's no CISA KEV listing, no public exploit, and no EPSS data yet, so this hasn't been weaponized in the wild, but the pattern is now public and is the fourth in a series with the same root cause (CVE-2026-22607, CVE-2025-67748, CVE-2025-67747), meaning it's trivially generalizable to the next unlisted stdlib module. Patch to fickling 0.1.11 immediately in any model-scanning or CI/CD ingestion pipeline, and stop treating a LIKELY_SAFE verdict from fickling as a substitute for sandboxed execution of untrusted pickle files.

Sources: NVD GitHub Advisory CISA KEV EPSS ATLAS

What is the risk?

High severity (CVSS 8.8) but not yet weaponized: no CISA KEV entry, no public exploit code, and no EPSS score, so real-world exploitation likelihood is currently unknown/low. However, exploitability is straightforward for anyone who understands pickle internals — attack complexity is LOW and no privileges are required, only user interaction (the victim's pipeline calling fickling.load() on the malicious file). The real risk driver is scope: this isn't a flaw in a random package, it's a flaw in the security control organizations adopted specifically to make pickle deserialization safe, so the exposure is concentrated in teams that made a deliberate, security-conscious choice to use fickling and now have a false sense of protection. Impact is maximal (C:H/I:H/A:H) since successful exploitation is full arbitrary code execution on the host performing the deserialization.

How does the attack unfold?

Craft malicious artifact
Adversary builds a pickle payload using the SETITEMS opcode pattern to evade UnusedVariables detection while invoking _posixsubprocess.fork_exec, site.execsitecustomize, or atexit._run_exitfuncs.
AML.T0018.002
Distribute as trusted model
The payload is disguised as a legitimate model checkpoint and published to a model hub/registry or sent directly to the target.
AML.T0058
False security clearance
Victim's pipeline calls fickling.load(), whose check_safety() misses the payload because the invoked modules aren't in the denylist, returning LIKELY_SAFE.
AML.T0011.000
Code execution impact
pickle.loads() proceeds and the payload executes, spawning arbitrary processes or code on the host that performed the deserialization.
AML.T0050

What systems are affected?

Package Ecosystem Vulnerable Range Patched
Fickling pip No patch
662 OpenSSF 7.8 61 dependents Pushed 4d ago 88% patched ~5d to patch Full package profile →

Do you use Fickling? You're affected.

How severe is it?

CVSS 3.1
8.8 / 10
EPSS
0.4%
chance of exploitation in 30 days
Higher than 30% of all CVEs
Exploitation Status
Exploit Available
Exploitation: MEDIUM
Sophistication
Advanced
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 is the attack surface?

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

What should I do?

1 step
  1. Upgrade fickling to 0.1.11 or later immediately, which adds _posixsubprocess, site, and atexit to the UNSAFE_IMPORTS denylist (see commit e8408615 and PR #272). Do not treat any fickling version's LIKELY_SAFE verdict as sufficient on its own — pair it with sandboxed/isolated deserialization (containers, gVisor, restricted seccomp profiles) for any pickle originating outside your organization. Where feasible, migrate model storage to non-executable formats like safetensors instead of pickle to eliminate this class of risk entirely. For detection, audit logs/EDR for anomalous child-process spawns or unexpected site-customization/exit-handler execution originating from Python processes that load ML artifacts, and flag any pickle payload containing SETITEMS-heavy opcode sequences during ingestion.

What does CISA's SSVC say?

Decision Attend
Exploitation poc
Automatable No
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
Annex A.6.2.6 - Third-party and customer relationships
NIST AI RMF
MEASURE 2.7 - AI system security and resilience are evaluated and documented
OWASP LLM Top 10
LLM05:2025 - Supply Chain Vulnerabilities

Frequently Asked Questions

What is CVE-2026-14534?

Fickling is Trail of Bits' security gate meant to block malicious pickle files before they're deserialized, but its denylist omits three standard-library modules — _posixsubprocess, site, and atexit — that a crafted pickle can invoke to spawn arbitrary processes, run injected code, or trigger callback execution, and check_safety() waves the payload through as LIKELY_SAFE with zero findings. This matters because any pipeline that trusts fickling.load() as a gatekeeper before loading a downloaded model checkpoint or dataset pickle now has a false sense of security — a poisoned .pkl or .pt file disguised as a legitimate model can achieve full remote code execution the moment it's loaded, and the CVSS 8.8 score (AV:N/AC:L/PR:N) reflects how low the bar is once a victim is convinced to open the file. There's no CISA KEV listing, no public exploit, and no EPSS data yet, so this hasn't been weaponized in the wild, but the pattern is now public and is the fourth in a series with the same root cause (CVE-2026-22607, CVE-2025-67748, CVE-2025-67747), meaning it's trivially generalizable to the next unlisted stdlib module. Patch to fickling 0.1.11 immediately in any model-scanning or CI/CD ingestion pipeline, and stop treating a LIKELY_SAFE verdict from fickling as a substitute for sandboxed execution of untrusted pickle files.

Is CVE-2026-14534 actively exploited?

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

How to fix CVE-2026-14534?

Upgrade fickling to 0.1.11 or later immediately, which adds _posixsubprocess, site, and atexit to the UNSAFE_IMPORTS denylist (see commit e8408615 and PR #272). Do not treat any fickling version's LIKELY_SAFE verdict as sufficient on its own — pair it with sandboxed/isolated deserialization (containers, gVisor, restricted seccomp profiles) for any pickle originating outside your organization. Where feasible, migrate model storage to non-executable formats like safetensors instead of pickle to eliminate this class of risk entirely. For detection, audit logs/EDR for anomalous child-process spawns or unexpected site-customization/exit-handler execution originating from Python processes that load ML artifacts, and flag any pickle payload containing SETITEMS-heavy opcode sequences during ingestion.

What systems are affected by CVE-2026-14534?

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

What is the CVSS score for CVE-2026-14534?

CVE-2026-14534 has a CVSS v3.1 base score of 8.8 (HIGH). The EPSS exploitation probability is 0.37%.

What is the AI security impact?

Affected AI Architectures

model servingtraining pipelinesMLOps pipelinesmodel supply chain / registries

MITRE ATLAS Techniques

AML.T0010.003 Model
AML.T0011.000 Unsafe AI Artifacts
AML.T0018.002 Embed Malware
AML.T0050 Command and Scripting Interpreter
AML.T0058 Publish Poisoned Models

Compliance Controls Affected

EU AI Act: Article 15
ISO 42001: Annex A.6.2.6
NIST AI RMF: MEASURE 2.7
OWASP LLM Top 10: LLM05:2025

What are the technical details?

Original Advisory

Trail of Bits fickling versions up to and including 0.1.10 do not include the Python standard library modules _posixsubprocess, site, and atexit in the UNSAFE_IMPORTS denylist (fickle.py). Because these modules are absent from the denylist, fickling's check_safety() function returns LIKELY_SAFE with zero findings for pickle payloads that invoke dangerous functions including _posixsubprocess.fork_exec (C-level process spawner capable of executing arbitrary binaries), site.execsitecustomize (executes arbitrary site customization code), and atexit._run_exitfuncs (triggers all registered exit handler callbacks). The fickling.load() API chains check_safety() into pickle.loads() as an explicit security gate; a LIKELY_SAFE verdict causes the payload to be deserialized and executed. This shares the same root cause as CVE-2026-22607 (cProfile), CVE-2025-67748 (pty), and CVE-2025-67747 (marshal/types). OvertlyBadEvals does not flag these modules because they are standard library imports. UnsafeImports does not flag them because they are not in the denylist. The UnusedVariables heuristic is defeated by the SETITEMS opcode pattern.

Exploitation Scenario

An adversary crafts a malicious pickle file disguised as a fine-tuned model checkpoint, embedding a payload that uses the SETITEMS opcode pattern to defeat fickling's UnusedVariables heuristic while invoking _posixsubprocess.fork_exec (or site.execsitecustomize / atexit._run_exitfuncs) to execute an arbitrary binary or reverse shell. They publish the file to a public model hub or send it directly to a target organization as a 'community fine-tune'. The victim's automated ingestion pipeline calls fickling.load() as a security gate; check_safety() misses the payload because the invoked modules aren't in the denylist, returns LIKELY_SAFE, and the pipeline proceeds to pickle.loads() the file — executing the attacker's code on the training or serving host, potentially exposing cloud credentials, training data, or providing a foothold for lateral movement.

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:R/S:U/C:H/I:H/A:H

Timeline

Published
July 4, 2026
Last Modified
July 10, 2026
First Seen
July 4, 2026

Related Vulnerabilities