Attack ChainAIDerived
Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain
-
ReconCraft pickle with non-denylisted stdlib import
-
DeliveryDeliver as model file to victim
-
ExploitVictim runs fickling.load() safety gate
-
InstallMLAllowlist check silently skipped
-
C2check_safety() returns LIKELY_SAFE
-
Executepickle.loads() executes payload
-
ImpactArbitrary code execution on host
Vulnerability Assessment
| Weakness |
CWE
OWASP Top 10:2025
A06:2025 - Insecure Design
ASVS 5.0
V15 - Secure Coding and Architecture Protection mechanism completeness
|
| Exploitation Conditions | Exploitation requires that the victim uses fickling ≤0.1.11 as a security gate-specifically fickling.load() or check_safety()-on an attacker-controlled pickle, and that the malicious payload relies on a module NOT present in fickling's UNSAFE_IMPORTS denylist (e.g., otherwise-benign standard-library imports) that MLAllowlist would normally have rejected. No special fickling configuration or non-default mode is needed: the reported_shortened_code poisoning occurs on every run of the default analysis chain. Limiting factors that reduce real-world risk: the attacker must get the crafted pickle to a system that actually trusts fickling's verdict before deserializing, so environments that never process untrusted pickles, that sandbox deserialization, or that have upgraded to 0.1.12 are not exposed; the CVSS PR:N/UI:N rating treats delivery-and-processing of the untrusted file as inherent to fickling's use case rather than requiring interactive user action. |
| Impact | The input CVSS 3.1 vector (AV:N/AC:L/PR:N/UI:N, C/I/A:H = 9.8) reflects the downstream impact-arbitrary code execution via unsafe deserialization-rather than a directly network-reachable bug, since fickling itself is a library whose failure only manifests when a victim runs check_safety()/fickling.load() on an attacker-supplied pickle. SSVC characterizes this precisely: Exploitation 'poc', Automatable 'no', Technical Impact 'total'-total impact but no evidence of scaled, automated exploitation. EPSS is low (0.30%, 22nd percentile) and the CVE is not in CISA KEV, so this is a serious latent supply-chain risk rather than a confirmed mass-exploitation event. The key nuance defenders must weigh: the raw 9.8 assumes the pickle reaches the parser over the network with no privileges, but real exploitation additionally requires that the victim actually relies on fickling as its security gate and processes untrusted pickles-making this a defense-in-depth failure whose real-world severity depends heavily on deployment. No signals conflict; the low EPSS plus 'poc' status are consistent with a freshly disclosed bypass that has a working demonstration but no widespread weaponization yet. |
| Exploit ScenarioDerived | An attacker publishes a malicious ML model (or otherwise supplies a pickle) whose payload imports a standard-library module absent from fickling's UNSAFE_IMPORTS denylist to gain code execution during unpickling. A victim on fickling ≤0.1.11 calls fickling.load() (or check_safety()) as their safety gate; MLAllowlist never evaluates the import, check_safety() returns LIKELY_SAFE, and pickle.loads() runs the payload. Given SSVC 'poc' and the advisory's regression tests demonstrating the bypass, working exploit logic is public, and the AV:N/AC:L profile means no special positioning is needed beyond delivering the file. |
Get an e-mail when this CVE is exploited, patched or re-scored. Free account.
Alert meAnalysisAIv3 – Jul 10, 2026
Security-control bypass in Trail of Bits fickling (≤0.1.11) neuters its MLAllowlist analysis pass so that malicious pickle files pass fickling's check_safety() gate as LIKELY_SAFE, enabling arbitrary code execution when fickling.load() deserializes them. Because UnsafeImportsML pre-registers every import in the shared reported_shortened_code set, MLAllowlist always short-circuits and never validates imports against the known-safe ML ecosystem, so any standard-library module outside the UNSAFE_IMPORTS denylist can be smuggled through. Publicly available exploit code exists (SSVC 'poc'); it is not listed in CISA KEV and EPSS is low (0.30%), consistent with a demonstrated-but-not-yet-widespread threat.
Earlier versions of this analysis (2)
Security-control bypass in Trail of Bits fickling (≤0.1.11) neutralizes the MLAllowlist safety check, causing malicious pickle payloads to be graded LIKELY_SAFE and executed. Because fickling.load() chains check_safety() into pickle.loads() as its security gate, an attacker who supplies a crafted model file achieves arbitrary code execution against any application relying on fickling to vet untrusted pickles. SSVC lists proof-of-concept exploit code exists; EPSS is low (0.30%, 22nd percentile) and the flaw is not in CISA KEV, so exploitation is possible but not yet widespread.
Security-control bypass in Trail of Bits fickling (versions up to and including 0.1.11) allows a malicious pickle to receive a LIKELY_SAFE verdict and be deserialized despite carrying an unauthorized import. The MLAllowlist analysis pass — intended to catch modules outside the known-safe ML ecosystem that evade the UnsafeImports denylist — is rendered dead code because the UnsafeImportsML pass poisons a shared deduplication set, so any non-denylisted standard-library module executes through fickling.load(). No public exploit is identified at time of analysis, but the fix is confirmed in v0.1.12; EPSS and KEV data were not provided.
RemediationAI
Vendor-released patch: 0.1.12-upgrade fickling to 0.1.12 or later (pip install --upgrade 'fickling>=0.1.12'), which refactors shorten_code() into a pure formatter plus an explicit mark_reported() call and unregisters MLAllowlist from automatic dedup so it always runs; see PR https://github.com/trailofbits/fickling/pull/278, commit 41ce7cb01edd97072994039574a2301ebb3f463d, and release https://github.com/trailofbits/fickling/releases/tag/v0.1.12. Until you can upgrade, do not treat a fickling LIKELY_SAFE verdict as authoritative on ≤0.1.11: refuse to load pickles from untrusted or unauthenticated sources, and prefer non-pickle formats such as safetensors where feasible-trade-off is that this blocks legitimate pickle-based workflows and may require converting existing model artifacts. As a stronger compensating control, deserialize any untrusted pickle only inside a sandboxed, network-isolated, least-privilege process (restricted syscalls/filesystem, no outbound egress) so a bypassed check cannot escalate to full host compromise; the trade-off is added operational complexity and the sandbox itself must be correctly locked down.
Affected VersionsENISA
Affected Packages
Source: OSV (Open Source Vulnerabilities)
Affects your stack
Affects 1 package in pypi
Checking this CVE against your own stacks and servers is part of the Basic plan and up.
Technical ContextAI · show details
fickling is Trail of Bits' pickle security and reverse-engineering tool used to statically screen Python pickle streams (commonly ML model files) before deserialization. Per CPE cpe:2.3:a:trailofbits:fickling, all versions through 0.1.11 are affected. Its safety verdict is produced by a chain of independent Analysis passes over the pickle AST. Two passes matter here: UnsafeImportsML flags imports on a denylist, and MLAllowlist is the positive control meant to reject imports NOT in the known-safe ML allowlist (torch, numpy, transformers, etc.). Both share a single AnalysisContext.reported_shortened_code deduplication set. UnsafeImportsML unconditionally called shorten_code(node) on every import, registering it in that set; MLAllowlist then saw already_reported=True and executed 'continue', skipping its allowlist check for every import. This maps to CWE-693 (Protection Mechanism Failure): each pass is individually correct, but shared mutable state silently disables the second, defeating the layered defense rather than corrupting memory or logic within a single component.
Know when Fickling gets its next vulnerability
- Watch products and get an email when something new is published
- Check this CVE against your own stack and servers
- Exploit and PoC references, threat intelligence from 22 sources
No credit card · 7-day full trial
Severity by source
AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
Failure of fickling's safety gate lets an attacker-supplied pickle achieve full code execution during automated ML model loading, so AV:N/AC:L/PR:N/UI:N with total C/I/A impact.
Primary rating from Vendor (BombadilSystems).
CVSS VectorNVD
Lifecycle Timeline
4DescriptionNVD
In Trail of Bits fickling versions up to and including 0.1.11, the UnsafeImportsML analysis pass unconditionally calls AnalysisContext.shorten_code(node) on every import node it inspects, regardless of whether the import is flagged as unsafe. This call registers the shortened code representation in the shared AnalysisContext.reported_shortened_code set. When the MLAllowlist analysis pass subsequently runs, it calls the same shorten_code() method, receives already_reported=True for every import, and executes a continue statement that skips its allowlist check entirely. This renders MLAllowlist dead code for all imports - it never evaluates whether an import is in the ML allowlist or not. The MLAllowlist pass was designed to catch imports of modules outside the known-safe ML ecosystem (torch, numpy, transformers, etc.) that slip past the UnsafeImports denylist. With MLAllowlist inoperative, any standard library module not in the UNSAFE_IMPORTS denylist can be invoked via pickle deserialization while fickling's check_safety() returns LIKELY_SAFE. The fickling.load() API chains check_safety() into pickle.loads() as an explicit security gate, meaning a LIKELY_SAFE verdict causes the payload to be deserialized and executed. The root cause is shared mutable state between independently-correct analysis passes - UnsafeImportsML works as designed in isolation, MLAllowlist works as designed in isolation, but the shared reported_shortened_code set causes UnsafeImportsML to poison MLAllowlist's deduplication logic.
Blast Radius
ecosystem impact- 62 pypi packages depend on fickling (10 direct, 53 indirect)
Ecosystem-wide dependent count for version 0.1.12.
Executive ViewAI
Trail of Bits fickling, a security tool designed to validate pickle files before deserialization, contains a critical control bypass that completely disables its safety checks and allows malicious pickles to execute arbitrary code. Organizations using fickling version 0.1.11 or earlier-including data science teams, ML infrastructure, and systems processing untrusted serialized objects-face direct code execution exposure with no vendor patch currently available. The vulnerability is public and proof-of-concept code exists, requiring immediate operational mitigations.
No vendor-released patch identified at time of analysis. Interim mitigations: (1) Restrict fickling processing to trusted pickle sources with verification; (2) Implement network segmentation to isolate systems handling pickles and limit code execution blast radius; (3) Disable untrusted pickle deserialization entirely where operationally feasible; (4) Enable logging and alerting on all pickle file processing; (5) For new development, migrate away from pickle to safer serialization formats (JSON, Protocol Buffers).
Threat Intelligence Overview
How this decision was reached
The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.
What every action level means
SSVC AssessmentENISA
Priority Score
Attack Technique
Insecure deserialization occurs when an application converts serialized data (a stream of bytes representing an object's state) back into a living object without proper validation.
Fickling's static analyzer through version 0.1.6 fails to properly classify the cProfile module as unsafe during pickle
Fickling's incomplete pickle analysis allows attackers to bypass security checks by using Python's runpy module to execu
Fickling's static analyzer before version 0.1.7 fails to detect several dangerous Python modules in pickled objects, ena
Trail of Bits Fickling versions before 0.1.6 fail to flag malicious pickles as unsafe because the `pty` module was omitt
Deserialization of an attacker-supplied pickle file that has been vetted by Fickling versions prior to 0.1.6 can execute
Arbitrary code execution bypass in Trail of Bits fickling (versions ≤ 0.1.10) allows attackers to craft malicious pickle
Pickle-analysis bypass in Trail of Bits fickling through 0.1.12 and vendor master commit d011709 allows arbitrary code e
fickling through 0.1.12 misclassifies malicious pickle payloads as safe: its OvertlyBadEvals analysis pass skips any cal
Fickling versions prior to 0.1.7 fail to properly detect malicious pickle payloads due to inadequate handling of the "bu
Fickling before version 0.1.7 allows local attackers to achieve arbitrary code execution through Python pickle deseriali
EUVD-2026-41676
GHSA-mgx3-9w7v-8674
NVD
CVE.org
EPSS
Vulnrichment
VulDB
Exploit-DB