CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



GHSA-5HWF-RC88-82XM

CVE-2026-22609: Incomplete Blocklist in Fickling Pickle Analyzer Leads to Arbitrary Code Execution

Alon Barad
Alon Barad
Software Engineer

Mar 4, 2026·7 min read·35 visits

Executive Summary (TL;DR)

Fickling < 0.1.7 fails to detect malicious pickle files that utilize dangerous standard library modules like `ctypes` and `runpy` due to an incomplete hardcoded blocklist. This allows attackers to bypass the security scanner and achieve Arbitrary Code Execution (ACE) on systems relying on Fickling for validation.

A critical logic vulnerability exists in Fickling versions prior to 0.1.7, allowing attackers to bypass the library's security analysis. Fickling, a static analysis tool designed to detect malicious Python pickle files, relied on an incomplete blocklist (denylist) of dangerous modules. The analysis engine failed to flag imports of high-risk standard library modules such as `ctypes`, `runpy`, and `importlib`. Consequently, an attacker can craft a malicious pickle file that executes arbitrary code while Fickling erroneously classifies the file as "LIKELY_SAFE." This effectively neutralizes the tool's purpose as a security gate for untrusted serialized data.

Vulnerability Overview

Fickling is a specialized static analysis tool developed to inspect Python pickle files—a serialization format known for its inherent security risks. The tool operates by symbolically executing the pickle machine's opcodes (such as GLOBAL, STACK_GLOBAL, and REDUCE) to reconstruct the Abstract Syntax Tree (AST) of the code that would execute upon deserialization. Fickling's primary objective is to identify malicious intent, such as the invocation of os.system or subprocess.Popen, allowing security teams to filter out dangerous files before they are loaded by the Python interpreter.

CVE-2026-22609 identifies a fundamental flaw in Fickling's detection logic. The analyzer employed a "denylist" approach, maintaining a hardcoded tuple of module names deemed unsafe. However, this list was not exhaustive. It omitted several powerful Python standard library modules that provide execution primitives capable of bypassing the Python runtime's intended constraints. Furthermore, the logic used to validate module paths was insufficient, allowing submodules or specific import patterns to evade detection.

The impact of this vulnerability is significant because Fickling is often deployed as a security gate in Machine Learning (ML) pipelines to validate untrusted models (which are often pickled data). By exploiting this flaw, an attacker can supply a malicious model that Fickling certifies as safe, but which subsequently compromises the downstream system consuming the model.

Root Cause Analysis

The vulnerability stems from the implementation of the unsafe_imports() method within fickling/fickle.py. This method is responsible for iterating over the AST nodes generated during the symbolic execution of the pickle file. It compares the module names targeted by GLOBAL or STACK_GLOBAL opcodes against a predefined set of forbidden strings.

The Incomplete Blocklist (CWE-184) The primary failure was the omission of critical modules from the UNSAFE_IMPORTS collection. Prior to version 0.1.7, the list lacked the following modules:

  • ctypes: Provides C-compatible data types and allows calling functions in DLLs/shared libraries. This can be used to invoke libc.system directly, bypassing Python's os module checks.
  • runpy: Designed to locate and execute Python modules without importing them first. Functions like run_path can execute arbitrary script files.
  • importlib: Provides the implementation of the import statement. Attackers can use it to dynamically load other blocked modules or execute arbitrary code during the import process.
  • multiprocessing: Can spawn new processes, potentially executing arbitrary shell commands.
  • code: Provides facilities to implement read-eval-print loops, which can be abused to execute arbitrary Python code strings.

Logic Flaws in Detection Beyond the missing entries, the detection logic contained structural flaws. First, the string matching was too rigid. It often checked for exact matches on the top-level package, meaning that if an attacker imported a submodule (e.g., ctypes.util) in a specific way, the check might be bypassed depending on how the opcode argument was structured. Second, Fickling explicitly suppressed the generation of AST nodes for builtins, __builtin__, and __builtins__. This exclusion was intended to reduce noise but inadvertently hid calls to dangerous built-in functions (like eval or __import__) from the safety check routine entirely.

Code Analysis

The following analysis contrasts the vulnerable implementation with the remediated code in version 0.1.7. The changes focus on expanding the blocklist and refining the validation logic.

Vulnerable Implementation (Concept) In earlier versions, the check was a simple membership test against a limited tuple. If the module wasn't in the tuple, it was yielded as safe or ignored.

# fickling/fickle.py (Pre-patch)
UNSAFE_IMPORTS = ("os", "subprocess", "sys", ...)
 
# Inside unsafe_imports()
if node.module in UNSAFE_IMPORTS:
    yield node

Remediated Implementation The patch introduces a comprehensive list of dangerous modules and refactors the check to inspect every component of the dotted module path. This prevents bypasses where a submodule is imported.

# fickling/fickle.py (Patched in v0.1.7)
 
# 1. Expanded Blocklist
UNSAFE_IMPORTS = {
    "os", "subprocess", "sys", "eval", "exec",
    "shutil", "platform", "ctypes",          # Added
    "runpy", "importlib", "code",            # Added
    "multiprocessing", "cProfile", "pydoc"   # Added
}
 
# 2. Enhanced Path Validation
# The analyzer now splits the module path and checks if ANY part is unsafe.
# e.g., 'ctypes.util' -> checks 'ctypes' AND 'util'.
if node.module and any(component in UNSAFE_IMPORTS for component in node.module.split(".")):
    yield node
 
# 3. Removal of Builtin Suppression
# The logic that previously ignored 'builtins' was removed to ensure
# access to dangerous builtins is visible to the analyzer.

The fix transforms the detection from a shallow string match to a more robust component-wise validation, significantly reducing the attack surface for import-based evasion.

Exploitation

To exploit this vulnerability, an attacker must craft a pickle file that utilizes one of the unmonitored modules to execute code. Standard pickle exploitation often relies on the __reduce__ method, which dictates how an object is pickled and unpickled. When unpickled, the GLOBAL opcode imports the specified module and returns a callable, and REDUCE executes that callable with provided arguments.

Scenario: ctypes Bypass The ctypes module allows interaction with C data types and shared libraries. An attacker can use ctypes.CDLL to load the standard C library (libc.so.6 on Linux) and invoke the system function. Because ctypes was missing from the UNSAFE_IMPORTS list, Fickling would parse the opcodes, see the import of ctypes, fail to match it against the blocklist, and conclude the file is safe.

Proof of Concept (PoC) The following Python snippet generates a pickle payload that executes id via ctypes. This payload successfully bypasses Fickling < 0.1.7.

import pickle
 
# The opcode sequence roughly translates to:
# GLOBAL 'ctypes' 'CDLL'  -> import ctypes; push ctypes.CDLL
# STRING 'libc.so.6'      -> push argument
# REDUCE                  -> call ctypes.CDLL('libc.so.6') -> returns libc handle
# ... (subsequent calls to resolve 'system' and call it)
 
# Payload construction using raw bytes for clarity:
# c = GLOBAL opcode
# ( = MARK
# t = TUPLE
# R = REDUCE
 
payload = b"cctypes\nCDLL\n(S'libc.so.6'\ntR(S'system'\ntR(S'id'\ntR."

When this payload is analyzed by a vulnerable version of Fickling, the result is Severity.LIKELY_SAFE. When loaded by a victim application using pickle.loads(), it executes the id command immediately.

Impact Assessment

The vulnerability represents a critical failure in the security controls provided by the library. Fickling is explicitly marketed as a tool to detect malicious pickles; failing to detect standard library exploits renders the tool ineffective for its primary use case.

Technical Impact

  • Arbitrary Code Execution (ACE): Successful exploitation grants the attacker full code execution privileges in the context of the application parsing the pickle.
  • Data Confidentiality: Attackers can read sensitive files, environment variables, or database credentials.
  • Integrity: Attackers can modify data, install persistence mechanisms, or pivot to other systems on the network.

Business Impact Organizations integrating Fickling into automated pipelines (e.g., for scanning uploaded Machine Learning models) face the highest risk. If a pipeline automatically deploys a model deemed "safe" by Fickling, an attacker could introduce a backdoor into production inference servers. The vulnerability has a CVSS v4.0 score of 8.9 (High), reflecting the high impact on Confidentiality, Integrity, and Availability with a low attack complexity.

Mitigation & Remediation

The primary remediation is to upgrade the Fickling library to version 0.1.7 or later. This version includes the expanded blocklist and improved validation logic.

Immediate Actions

  1. Identify Vulnerable Instances: Scan dependency trees for fickling < 0.1.7.
  2. Upgrade: Update to the latest version using pip: pip install --upgrade fickling.
  3. Rescan Artifacts: Any pickle files previously marked as safe by the vulnerable version should be quarantined and re-analyzed with the patched version.

Strategic Recommendations Security teams should recognize that blocklisting (enumerating "bad" things) is inherently fragile compared to allowlisting (enumerating "good" things). The Python pickle format is Turing-complete and notoriously difficult to secure.

  • Avoid Pickles: Where possible, transition to safer serialization formats. For Machine Learning models, use Safetensors or ONNX, which are designed to store tensors without executable code capabilities.
  • Sandboxing: If pickle processing is unavoidable, ensure it occurs within a strictly isolated sandbox (e.g., ephemeral containers, gVisor, or restricted microVMs) with no access to sensitive networks or data.

Official Patches

Trail of BitsFickling GitHub Repository

Fix Analysis (4)

Technical Appendix

CVSS Score
8.9/ 10
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N/E:P

Affected Systems

Fickling < 0.1.7Machine Learning pipelines using Fickling for model validationPython applications using Fickling to scan untrusted pickles

Affected Versions Detail

Product
Affected Versions
Fixed Version
fickling
trailofbits
< 0.1.70.1.7
AttributeDetail
CWE IDCWE-184
CWE NameIncomplete List of Disallowed Inputs
Attack VectorNetwork / Local (File)
CVSS v4.08.9 (High)
CVSS v3.17.8 (High)
Exploit StatusPoC Available

MITRE ATT&CK Mapping

T1204.002Malicious File
Execution
T1059.006Command and Scripting Interpreter: Python
Execution
T1588.006Obtain Capabilities: Vulnerabilities
Resource Development
CWE-184
Incomplete List of Disallowed Inputs

The product receives input from an upstream component, but it does not restrict or incorrectly restricts the input to a set of valid inputs, allowing for the processing of invalid or malicious data.

Known Exploits & Detection

GitHubVerified PoC in test suite demonstrating runpy bypass

Vulnerability Timeline

Fix commits for ctypes, runpy, and pydoc bypasses
2026-01-07
Fix commits for importlib, code, and multiprocessing
2026-01-08
Fix commit for path component validation
2026-01-09
Version 0.1.7 released
2026-01-09
CVE-2026-22609 published
2026-01-10

References & Sources

  • [1]Fickling Repository

More Reports

•1 day ago•CVE-2026-11748
6.9

CVE-2026-11748: Unauthenticated LDAP Injection in Central Dogma Server Authentication

An LDAP injection vulnerability exists in the centraldogma-server-auth-shiro module of LY Corporation Central Dogma before version 0.84.0. The search logic dynamically constructs LDAP search filters by interpolating user-provided usernames without escaping RFC 4515 metacharacters. Unauthenticated remote attackers can leverage this flaw to bypass authentication, enumerate directory hierarchies, and access unauthorized resources.

Alon Barad
Alon Barad
9 views•6 min read
•1 day ago•CVE-2026-11746
9.4

CVE-2026-11746: Use of Hard-coded ZooKeeper Replication Secret 'ch4n63m3' in Central Dogma Server

CVE-2026-11746 is a critical vulnerability in Central Dogma Server prior to version 0.84.0, where an embedded ZooKeeper replication secret silently falls back to a publicly known, hard-coded default string ('ch4n63m3'). Remote attackers with access to the replication network can authenticate as legitimate cluster peers, potentially leading to unauthorized data exposure, state manipulation, or complete cluster takeover.

Amit Schendel
Amit Schendel
7 views•6 min read
•1 day ago•CVE-2026-56665
4.2

CVE-2026-56665: Logical Validation Bypass in ZITADEL External JWT Identity Provider

A logical verification flaw in ZITADEL's external JWT Identity Provider validation allows attackers to bypass session expiration checks. If an incoming JWT lacks the 'exp' claim, the system skips validation entirely, creating an indefinitely valid session. This issue has been addressed in versions 3.4.12 and 4.15.2.

Alon Barad
Alon Barad
6 views•7 min read
•1 day ago•CVE-2026-59149
6.5

CVE-2026-59149: Sibling Directory Path Traversal in Mockoon Backend Server

CVE-2026-59149 identifies a directory traversal vulnerability in `@mockoon/commons-server`, the backend mock-server library powering the Mockoon application. The flaw occurs in the path containment validation logic used during raw file response generation. An unauthenticated attacker can exploit this weakness to retrieve arbitrary files from sibling directories sharing a common prefix with the designated static base directory.

Amit Schendel
Amit Schendel
9 views•5 min read
•1 day ago•CVE-2026-59148
8.8

CVE-2026-59148: Unauthenticated Administrative API and CORS Misconfiguration in Mockoon

An in-depth analysis of CVE-2026-59148, a high-severity flaw in Mockoon where unauthenticated administrative endpoints and a wildcard Cross-Origin Resource Sharing (CORS) policy allow remote execution, state poisoning, and credential theft.

Alon Barad
Alon Barad
11 views•6 min read
•1 day ago•CVE-2026-56666
4.8

CVE-2026-56666: Account Takeover via Improper Email Verification in ZITADEL Federated Identity Handler

An improper authentication vulnerability (CWE-287) in ZITADEL's external identity provider handler before version 4.15.3 allows remote attackers to perform complete account takeover. When auto-linking by email is enabled, ZITADEL verifies that the local target account has a verified email address but fails to verify if the external provider confirmed ownership of that same email. Attackers can exploit this by registering an unverified account with a victim's email address on a permissive external provider, leading to unauthorized account binding and persistent access.

Amit Schendel
Amit Schendel
7 views•7 min read