HIGH 8.8

CVE-2026-14534: Fickling Pickle Validator Bypass via Standard Library Modules

Fickling, a Python library designed to detect malicious pickle payloads before they execute, fails to block code execution via three standard library modules: _posixsubprocess, site, and atexit. An attacker can craft a specially formatted pickle file that exploits these blind spots, causing fickling's safety check to incorrectly report the payload as safe. When a developer uses fickling to load the pickle, the malicious code runs anyway. This is particularly dangerous because fickling is explicitly marketed as a security gate, so users trust its verdicts.

Source data · NVD / CISA · public domain

CVSS
3.1 · 8.8 HIGH · CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
Weaknesses (CWE)
CWE-184, CWE-502
Affected products
1 configuration(s)
Published / Modified
2026-07-04 / 2026-07-10

NVD description (verbatim)

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.

5 reference(s) · View on NVD →

SEC.co analysis · AI-assisted, reviewed against source

Technical summary

Fickling versions ≤0.1.10 omit _posixsubprocess, site, and atexit from the UNSAFE_IMPORTS denylist in fickle.py. The check_safety() function, which serves as a security validator, performs module inspection against this incomplete list. Absence from the denylist results in a LIKELY_SAFE classification with zero findings, even when the pickle opcode stream calls _posixsubprocess.fork_exec (a low-level process spawner), site.execsitecustomize (arbitrary code execution hook), or atexit._run_exitfuncs (callback chain trigger). The fickling.load() API chains check_safety() directly into pickle.loads(), meaning a LIKELY_SAFE verdict leads to immediate deserialization and execution. This vulnerability shares identical root cause patterns with related issues in cProfile (CVE-2026-22607), pty (CVE-2025-67748), and marshal/types (CVE-2025-67747). Both the OvertlyBadEvals and UnsafeImports heuristics fail: the former does not flag standard library imports, and the latter relies solely on the incomplete denylist. The SETITEMS opcode pattern also bypasses UnusafeVariables detection.

Business impact

Fickling is positioned as a safeguard for pickle deserialization—a known attack surface in Python supply chains. Organizations relying on fickling to validate untrusted pickle files (e.g., from user uploads, inter-service RPC, or cached datasets) may unknowingly execute arbitrary code from adversary-controlled payloads. The trust boundary is broken: a developer deploying fickling.load() as a security control gains false confidence. In production environments, this enables remote code execution (RCE) with the privileges of the Python process, potentially compromising data, lateral movement, or service disruption. The impact scales with deployment breadth—any application using fickling as a pickle safety gate is vulnerable.

Affected systems

Trail of Bits fickling versions up to and including 0.1.10 are affected. The vulnerability is present in the core fickle.py module and impacts all deployments that call the fickling.load() or check_safety() functions. Any environment parsing untrusted pickle data via fickling is at risk, regardless of Python version or OS, though exploitation mechanics (e.g., _posixsubprocess.fork_exec) are platform-specific in their payload mechanics.

Exploitability

Exploitation requires an attacker to craft a malicious pickle file and either (a) trick a user into loading it via fickling, or (b) place it in a data path an application trusts (upload endpoint, cache, message queue). The CVSS vector indicates network accessibility, low complexity, no privileges required, and user interaction (user must load the pickle). Once loaded, full code execution is achieved. No patch or workaround is documented yet, making this exploitable against all in-the-wild deployments of vulnerable versions.

Remediation

Upgrade fickling to a patched version that restores _posixsubprocess, site, and atexit to the UNSAFE_IMPORTS denylist and refines the heuristics (OvertlyBadEvals, UnsafeImports, UnusedVariables) to catch SETITEMS patterns. Verify the patch version against the official Trail of Bits fickling repository or security advisory. Pending a patch, do not use fickling as a sole security gate for untrusted pickle deserialization; instead, prefer alternatives such as restricting pickle to safe data formats (e.g., JSON or msgpack) or using restricted deserialization libraries like `pickle` with a custom `Unpickler` class that overrides `find_class()`.

Patch guidance

Monitor Trail of Bits' official fickling repository and security advisories for a patched release. Verify the fix addresses all three modules (_posixsubprocess, site, atexit) and strengthens heuristic detection of standard library abuses. Once available, test the patch in a staging environment before rolling out to production. Do not assume minor version bumps (e.g., 0.1.11) are sufficient; confirm the specific CVE-2026-14534 fix is included. For teams unable to upgrade immediately, implement a layer of data sanitization before pickling or avoid pickle altogether in favor of safer serialization formats.

Detection guidance

Monitor for pickle files or serialized data entering your environment, especially from user uploads or external APIs. Log all invocations of fickling.load() and check_safety() in your codebase. Implement runtime monitoring for child process spawning via _posixsubprocess.fork_exec, site.execsitecustomize hooks, and atexit handler registrations—these are legitimate in some contexts but suspicious when paired with pickle deserialization. Code review any integration of fickling to ensure it is not the sole security boundary for untrusted input. Examine pickle payloads for suspicious opcode patterns (GLOBAL or REDUCE operations targeting standard library introspection modules).

Why prioritize this

This is a HIGH-severity vulnerability (CVSS 8.8) in a library explicitly designed to prevent pickle exploitation. The false-sense-of-security aspect elevates urgency: developers may have deployed fickling under the assumption that it blocks these attacks. The scope spans any application accepting pickle input and trusting fickling's verdict. The vulnerability chain mirrors earlier oversights (cProfile, pty, marshal) indicating a systematic gap in standard library coverage. Immediate inventory and upgrade of fickling is critical.

Risk score, explained

The CVSS 3.1 score of 8.8 (HIGH) reflects: network-accessible attack surface (AV:N), low attack complexity (AC:L), no authentication required (PR:N), user interaction limited to loading the malicious file (UI:R), unchanged scope (S:U), and all three confidentiality, integrity, and availability impacts present (C:H/I:H/A:H). Remote code execution via pickle is a classical critical attack; the added risk stems from fickling's security-validator role—it lowers the barrier for attackers by giving false legitimacy to payloads.

Frequently asked questions

Does fickling protect against this attack after patching?

Patched versions of fickling will add _posixsubprocess, site, and atexit to the UNSAFE_IMPORTS denylist and strengthen heuristics. However, fickling should be treated as a *defense-in-depth* component, not a complete firewall. The safest approach remains avoiding pickle entirely for untrusted input or using alternative serialization formats.

Are all users of fickling affected?

Only users who call fickling.load() or check_safety() on untrusted pickle data are at risk. If your code loads pickle files only from trusted, internal sources (e.g., your own database), the practical risk is lower—but you should still upgrade to close the gap.

How do I know if my application uses an affected version?

Check your requirements.txt, Pipfile, or package metadata for fickling versions ≤0.1.10. Run `pip show fickling` or examine your lock files. If you do not explicitly use fickling, you are not affected unless a dependency includes it.

What is the difference between this CVE and the related cProfile/pty/marshal issues?

All four CVEs (this one, CVE-2026-22607, CVE-2025-67748, CVE-2025-67747) stem from incomplete UNSAFE_IMPORTS denylist coverage—different standard library modules each time. They represent a pattern of oversight in fickling's security model. Patches should address all known modules and improve the detection heuristics to avoid similar bypasses.

This analysis is based on the CVE record as of July 2026. Patch availability, version numbers, and remediation steps should be verified against Trail of Bits' official fickling repository and published security advisory. No exploit code is provided. The information herein is for defensive security planning only and should not be used to develop or test attacks. Organizations should conduct their own risk assessments and testing in controlled environments. SEC.co makes no warranty regarding the accuracy or completeness of this analysis. Source: NVD (public-domain), retrieved 2026-08-13. Analysis generated by SEC.co (claude-haiku-4-5).