Skip to main content

fickling CVE-2026-14535

| EUVDEUVD-2026-41676 CRITICAL
Protection Mechanism Failure (CWE-693)
2026-07-04 BombadilSystems GHSA-mgx3-9w7v-8674
9.8
CVSS 3.1 · NVD
Share

Severity by source

Vendor (BombadilSystems) PRIMARY
HIGH
qualitative
NVD
9.8 CRITICAL
AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
vuln.today AI
9.8 CRITICAL

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.

3.1 AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
4.0 AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
Red Hat
8.8 HIGH
qualitative

Primary rating from Vendor (BombadilSystems).

CVSS VectorNVD

Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
Confidentiality
High
Integrity
High
Availability
High

Lifecycle Timeline

7
Analysis Updated
Jul 10, 2026 - 15:14 vuln.today
v3 (cvss_changed)
Source Code Evidence Fetched
Jul 10, 2026 - 15:14 vuln.today
Analysis Updated
Jul 10, 2026 - 15:14 vuln.today
v2 (cvss_changed)
Re-analysis Queued
Jul 10, 2026 - 15:07 vuln.today
cvss_changed
Severity Changed
Jul 10, 2026 - 15:07 NVD
HIGH CRITICAL
CVSS changed
Jul 10, 2026 - 15:07 NVD
8.8 (HIGH) 9.8 (CRITICAL)
Analysis Generated
Jul 04, 2026 - 14:19 vuln.today

Blast Radius

ecosystem impact
† from your stack dependencies † transitive graph · vuln.today resolves 4-path depth
  • 62 pypi packages depend on fickling (10 direct, 53 indirect)

Ecosystem-wide dependent count for version 0.1.12.

DescriptionNVD

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.

AnalysisAI

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.

Technical ContextAI

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.

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.

Vendor StatusVendor

Share

CVE-2026-14535 vulnerability details – vuln.today

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy