Description
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.
Published: 2026-07-04
Score: 8.8 High
EPSS: < 1% Very Low
KEV: No
Impact: n/a
Action: n/a
AI Analysis

Impact

In versions of Trail of Bits Fickling up to 0.1.11, the UnsafeImportsML analysis pass registers every import node with a shared reported_shortened_code set regardless of whether the import is flagged unsafe. The following MLAllowlist pass then sees this set already populated, skips its allowlist check, and becomes effectively inert. As a result, imports of modules that are not in the UnsafeImports denylist—including standard library modules—can be executed when pickle data is deserialized via fickling.load(). This bypass of the safety gate allows an attacker to achieve arbitrary code execution through malicious pickle payloads, violating the integrity and confidentiality of the system. The flaw is an instance of improper control of resource location (CWE‑693).

Affected Systems

Trail of Bits Fickling versions 0.1.0 through 0.1.11 are affected. Any Python application that utilizes fickling.load() to deserialize untrusted pickle data is at risk.

Risk and Exploitability

The CVSS score of 8.8 categorizes the vulnerability as high severity for remote code execution. The EPSS score of less than 1% indicates a low probability of active exploitation, and the vulnerability is not listed in the CISA KEV catalog. The likely attack vector is an attacker supplying crafted pickle payloads to an application using fickling.load(), allowing execution of arbitrary code without requiring elevated system privileges.

Generated by OpenCVE AI on July 24, 2026 at 10:00 UTC.

Remediation

No vendor fix or workaround currently provided.

OpenCVE Recommended Actions

  • Upgrade the Trail of Bits fickling package to version 0.1.12 or later, which removes the shared mutable state bug that disables the MLAllowlist logic.
  • Restrict the use of fickling.load() so that it processes only data from trusted sources, or replace it with a safer deserialization routine that does not rely on the vulnerable MLAllowlist checks.
  • If upgrading immediately is not possible, execute pickle deserialization in a sandboxed or isolated process, or switch to an alternative deserialization library that does not depend on the faulty analysis passes.

Generated by OpenCVE AI on July 24, 2026 at 10:00 UTC.

Tracking

Sign in to view the affected projects.

Advisories

No advisories yet.

History

Wed, 08 Jul 2026 00:15:00 +0000

Type Values Removed Values Added
References
Metrics threat_severity

None

threat_severity

Important


Mon, 06 Jul 2026 16:30:00 +0000

Type Values Removed Values Added
Metrics ssvc

{'options': {'Automatable': 'no', 'Exploitation': 'poc', 'Technical Impact': 'total'}, 'version': '2.0.3'}


Sat, 04 Jul 2026 15:45:00 +0000

Type Values Removed Values Added
First Time appeared Trailofbits
Trailofbits fickling
Vendors & Products Trailofbits
Trailofbits fickling

Sat, 04 Jul 2026 14:00:00 +0000

Type Values Removed Values Added
Description 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.
Title Fickling MLAllowlist analysis pass rendered inoperative by shared mutable state in AnalysisContext.shorten_code()
Weaknesses CWE-693
References
Metrics cvssV3_1

{'score': 8.8, 'vector': 'CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H'}


Subscriptions

Trailofbits Fickling
cve-icon MITRE

Status: PUBLISHED

Assigner: BombadilSystems

Published:

Updated: 2026-07-06T14:58:34.718Z

Reserved: 2026-07-03T00:02:55.918Z

Link: CVE-2026-14535

cve-icon Vulnrichment

Updated: 2026-07-06T14:58:02.632Z

cve-icon NVD

No data.

cve-icon Redhat

Severity : Important

Publid Date: 2026-07-04T13:31:14Z

Links: CVE-2026-14535 - Bugzilla

cve-icon OpenCVE Enrichment

Updated: 2026-07-24T10:15:02Z

Weaknesses
  • CWE-693

    Protection Mechanism Failure