Attack ChainAIDerived
Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain
-
AccessCraft malicious pickle routed through whitelisted stdlib callable
-
DeliveryDeliver as ML model or pickle artifact
-
ExploitVictim scans with fickling check_safety()/load()
-
ExecutionScanner whitelists module origin, returns LIKELY_SAFE and deserializes
-
ImpactArbitrary code execution or file write as victim process
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 a victim running fickling version ≤0.1.12 processes an attacker-controlled pickle or model file through check_safety() or fickling.load() while treating the result as a security gate - this is the required user interaction (UI:R), not remote drive-by access. The malicious payload must invoke a callable reachable through a standard-library module that is present in sys.stdlib_module_names and absent from UNSAFE_IMPORTS; the demonstrated callables are version- and platform-limited: dataclasses._create_fn gives code execution only on Python 3.7-3.12 (the internal _create_fn was removed in 3.13), mailcap.findmatch gives code execution only through Python 3.12 (the mailcap module was removed in 3.13), and readline.add_history()/write_history_file() gives arbitrary file write only on POSIX platforms where the readline module is available. These three specific primitives are blocked on the vendor master branch (commit d011709), but the module-origin trust root cause is not fixed, so other stdlib-reachable callables remain a path on all released versions and on Python 3.13+. Key limiting factor: the attack only matters where fickling is actually relied upon to vet untrusted pickles; it does not expose a network service directly. |
| Impact | This is a genuine high-priority issue, but its severity is conditional on fickling being relied upon as a security gate rather than on broad internet exposure. The provided CVSS 3.1 vector (AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H, base 8.8) is consistent with the mechanism: an attacker needs no privileges, only that a victim (UI:R) processes an attacker-supplied pickle/model file through the vulnerable scanner. The vuln.today decision label is 'this_week', not 'act_now'/'emergency', which matches a serious-but-not-fire-drill posture. Critically, this is CWE-693 (protection-mechanism failure): fickling is itself a security tool, so the real-world impact is a false sense of safety - check_safety() returns LIKELY_SAFE with zero findings for payloads that achieve code execution or arbitrary file write. No EPSS score and no CISA KEV status were supplied, and the input does not confirm a packaged public exploit; absence of these signals is not evidence of low risk, but it means widespread automated exploitation is not demonstrated in the provided data. The dangerous combination is the intended use case: fickling is deployed precisely to vet untrusted ML pickle files, so the population most likely to run it is the population most exposed to malicious input. Net assessment: treat as a real priority for anyone using fickling in a scanning/loading pipeline, while recognizing exploitation is targeted at that specific trust relationship rather than opportunistic against the open internet. |
| Exploit ScenarioDerived | An attacker publishes a malicious ML model or pickle file (for example to a model hub or shared artifact store) whose payload reaches code execution through a standard-library callable such as dataclasses._create_fn or mailcap.findmatch. A victim running fickling ≤0.1.12 scans the file with check_safety() or opens it with fickling.load(), expecting the tool to block dangerous pickles; instead the scanner whitelists the stdlib-origin callable, returns LIKELY_SAFE, and fickling.load() deserializes the payload, executing attacker code with the victim process's privileges. The advisory demonstrates concrete working primitives for this bypass, but the supplied input does not confirm a standalone, packaged public exploit. |
Get an e-mail when this CVE is exploited, patched or re-scored. Free account.
Alert meAnalysisAIv1 – Oct 30, 2026
fickling through 0.1.12 misclassifies malicious pickle payloads as safe: its OvertlyBadEvals analysis pass skips any call whose name was added to the likely_safe_imports set purely because the source module appears in sys.stdlib_module_names, so check_safety() can return LIKELY_SAFE with zero findings for payloads that reach code execution or arbitrary file write. Because fickling.load() chains check_safety() into pickle.loads() as a security gate, a victim who runs unauthenticated, attacker-supplied pickle or model content through the tool (the required user interaction, UI:R) can end up executing that content with the privileges of the analysis process. The advisory demonstrates three concrete primitives - dataclasses._create_fn (Python 3.7-3.12), mailcap.findmatch (through Python 3.12) and readline.add_history()/write_history_file() on POSIX - while noting the underlying module-origin trust root cause is broader and remains unfixed; no public exploit code is referenced in the available intelligence and there is no KEV entry, but the tool's whole purpose is vetting untrusted pickles, so the severity is real for anyone relying on it as a gate.
RemediationAI
No patched release has been published: versions through 0.1.12 remain affected, and the only fix identified is on the vendor master branch, commit d011709 (https://github.com/trailofbits/fickling/commit/d011709), which adds the three demonstrated modules - dataclasses, mailcap and readline - to UNSAFE_IMPORTS pending release; note that the visible changes in that commit concern PyTorch data.pkl handling, and the advisory itself states the module-origin trust root cause is not resolved, so pinning to that build should not be treated as a complete fix. Until a release lands, do not rely on check_safety() or fickling.load() as an authorization gate for untrusted pickles; where the verdict is advisory only, downgrade its weight in your pipeline accordingly. Concretely: extend UNSAFE_IMPORTS locally with the demonstrated callables (dataclasses._create_fn, mailcap.findmatch, readline.add_history, readline.write_history_file) plus any other stdlib entry points your payloads can reach, accepting that denylists are incomplete by construction and that the related CVE-2026-118938 remains exploitable on that same build. Move the gate out of the trust boundary: perform the check_safety() verdict and any subsequent pickle.loads() inside a throwaway subprocess or container with no network, a read-only root filesystem, and no access to the operator's credentials or history files, so a false LIKELY_SAFE verdict caps the blast radius at the sandbox rather than the victim process privileges - the trade-off is loss of in-process speed and the need to marshal results out. On Python 3.13+, runtimes where mailcap and dataclasses._create_fn are gone and where readline may be absent are narrower but not safe, since the trust model, not the specific callables, is the defect. Block the affected versions from environments that deserialize third-party models automatically, and monitor the GitHub repository and the bombadil.systems advisory page for the release that ships commit d011709.
Affected VersionsENISA
Affected Packages
Source: OSV (Open Source Vulnerabilities)
Affects your stack
Affects 1 package in euvd
Checking this CVE against your own stacks and servers is part of the Basic plan and up.
Technical ContextAI · show details
fickling is a static/dynamic pickle analysis library and CLI from Trail of Bits used to decide whether a pickle is safe to deserialize. Two internal components are at fault. In fickle.py, _process_import() marks an imported name as trusted whenever the source module is present in Python's sys.stdlib_module_names and the name is not on the UNSAFE_IMPORTS denylist - it never inspects what the name actually resolves to or how it behaves. In analysis.py, the OvertlyBadEvals pass then unconditionally skips any call whose function name appears in that likely_safe_imports set, including calls it would otherwise flag as overtly dangerous. The result is that any callable reachable through a non-blocked standard-library module inherits module-level trust, which is a failure of the protection mechanism itself (CWE-693) rather than a flaw in pickle parsing. Three primitives are demonstrated: dataclasses._create_fn, which feeds an attacker-controlled function body to exec() on Python 3.7-3.12 (removed in 3.13); mailcap.findmatch, which calls os.system() on a test command drawn from an attacker-controlled caps dictionary on Python through 3.12 (module removed in 3.13); and readline.add_history() followed by readline.write_history_file(), which writes attacker-controlled content to an arbitrary path on POSIX systems where readline is available. The advisory explicitly separates this module-origin trust weakness from a dotted __qualname__ resolution weakness tracked as CVE-2026-118938, and states that the latter remains exploitable on the same master build, i.e. the root cause here is independent and separately fixable.
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:R/S:U/C:H/I:H/A:H
Attacker-supplied file delivered over network (AV:N), no privileges (PR:N), but a victim must deliberately scan/load the malicious pickle (UI:R); successful bypass yields full code execution, so C/I/A:H.
Primary rating from Vendor (BombadilSystems).
CVSS VectorVendor: BombadilSystems
DescriptionCVE.org
In Trail of Bits fickling through 0.1.12, the _process_import() method in fickle.py adds an imported name to the likely_safe_imports set whenever the source module is present in sys.stdlib_module_names and the name is absent from the UNSAFE_IMPORTS denylist, without inspecting what the name resolves to or how it behaves. The OvertlyBadEvals analysis pass in analysis.py then unconditionally skips any call whose function name appears in likely_safe_imports, including calls that would otherwise be flagged as overtly dangerous. As a result, any callable reachable through a non-blocked standard library module inherits module-level trust regardless of its own behavior, and check_safety() returns LIKELY_SAFE with zero findings for pickle payloads that reach code execution or file write through such callables. Demonstrated primitives: dataclasses._create_fn, which passes an attacker-controlled function body to exec() and yields arbitrary code execution on Python 3.7 through 3.12 (the internal _create_fn function was removed in Python 3.13); mailcap.findmatch, which internally calls os.system() on a test command taken from an attacker-controlled caps dictionary, yielding arbitrary code execution on Python versions through 3.12 (the mailcap module was removed in Python 3.13); and readline.add_history() followed by readline.write_history_file(), which writes attacker-controlled content to an arbitrary filesystem path (POSIX platforms, where the readline module is available). fickling.load() chains check_safety() into pickle.loads() as an explicit security gate, so a LIKELY_SAFE verdict causes the payload to be deserialized and executed with the privileges of the victim process. The root cause is the inference of callable safety from module origin; it is independent of, and separately fixable from, the dotted __qualname__ resolution weakness tracked as CVE-2026-118938, which this advisory does not address. As of 2026-10-30 the three demonstrated modules were added to UNSAFE_IMPORTS on the vendor master branch (commit d011709) pending release; released versions through 0.1.12 remain affected, and the module-origin trust root cause persists, as demonstrated by the related CVE-2026-118938 remaining exploitable on that same build.
Articles & Coverage 1
Executive ViewAI
CVE-2026-16760 (CVSS 8.8) is a HIGH-severity vulnerability in the Python library fickling (through 0.1.12) where its safety check can be bypassed, allowing malicious pickle or model content to execute with the analyzing process's privileges. Data scientists and security teams who use fickling to inspect untrusted ML models are at risk; a successful exploit could lead to arbitrary code execution or file write within your environment, undermining the security gate this tool is supposed to provide.
No vendor-released patch identified at time of analysis. Interim mitigations include: running fickling in a sandboxed, low-privilege container with no network access and limited filesystem write permissions; manually inspecting the pickle opcodes or using alternative static analysis tools before loading any model; and restricting the processing of pickle files to trusted sources only.
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
Remote Code Execution represents the critical moment when an attacker successfully runs arbitrary code on a target system without physical access.
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
Security-control bypass in Trail of Bits fickling (≤0.1.11) neuters its MLAllowlist analysis pass so that malicious pick
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 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-114513
GHSA-cgc3-662q-qmrc
NVD
CVE.org
EPSS
Exploit-DB