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-5CXW-W2XG-2M8H
7.5

GHSA-5CXW-W2XG-2M8H: Security Bypass via Incomplete Denylist in Fickling Pickle Analyzer

Amit Schendel
Amit Schendel
Senior Security Researcher

Mar 13, 2026·6 min read·3 visits

PoC Available

Executive Summary (TL;DR)

Fickling <= 0.1.9 utilizes an incomplete denylist that omits the 'platform' module. Attackers can bypass safety checks and achieve arbitrary file read or restricted command execution by referencing internal platform functions in a crafted pickle file.

Fickling versions 0.1.9 and earlier contain a high-severity security bypass vulnerability in the safety analyzer. The failure to include the Python standard library's platform module in the application's denylist allows attackers to craft malicious pickle files that execute arbitrary file reads and restricted system commands while being incorrectly validated as safe.

Vulnerability Overview

Fickling is a static analyzer and decompiler designed to evaluate Python pickle files for malicious payloads. Systems frequently deploy Fickling as a preliminary safety check before passing untrusted .pkl or .pth files to the native pickle.loads() function. The tool evaluates the opcodes within a pickle stream and checks referenced modules against an internal denylist to determine safety.

A high-severity security bypass vulnerability exists in Fickling versions 0.1.9 and earlier. The analyzer implements an incomplete list of disallowed inputs, tracking known dangerous modules like os and subprocess but omitting the standard library's platform module. This omission allows an attacker to construct malicious pickle files that utilize internal platform functions to achieve arbitrary file reads and restricted subprocess execution.

When the vulnerable Fickling engine analyzes these crafted payloads, it outputs a severity rating of LIKELY_SAFE and reports zero issues. Downstream systems relying on Fickling's verdict will subsequently deserialize the payload. This deserialization triggers the payload execution within the context of the application parsing the pickle file.

Root Cause Analysis

The root cause of this vulnerability lies in Fickling's reliance on an "allowlist-by-exclusion" mechanism within its check_safety() function. The application maintains a set named UNSAFE_IMPORTS that enumerates Python standard library modules recognized as dangerous. During the OvertlyBadEvals analysis phase, Fickling statically analyzes module imports against this set.

The Python platform module is primarily utilized for identifying runtime hardware and operating system environments. However, the module contains internal helper functions that wrap dangerous execution sinks. Specifically, platform._syscmd_file(target) executes the system file binary via subprocess.check_output, and platform.libc_ver(file) facilitates arbitrary file read operations.

Because platform was omitted from the UNSAFE_IMPORTS set, Fickling's validation logic skips evaluating calls to these internal functions. The analyzer treats the platform module as benign, inherently trusting any function exported by the module regardless of the underlying sink it interacts with. This structural flaw exposes the inherent limitations of denylist-based security controls when applied to large standard libraries.

Code Analysis

The vulnerable implementation relies on a statically defined list of modules within fickling/fickle.py. Prior to the patch, the module categorized dangerous imports into distinct functional areas such as file operations, networking, and system command execution. The system evaluated the GLOBAL opcode against this list to detect malicious function imports.

# Vulnerable implementation in fickling/fickle.py
UNSAFE_IMPORTS = {
    # ...
    "os",
    "subprocess",
    "shutil",
    "fileinput",
    "glob",
    "compileall",
    # platform module is entirely missing here
    # ...
}

The patch, implemented in commit 351ed4d4242b447c0ffd550bb66b40695f3f9975, resolves the immediate bypass by expanding the denylist. The developers added the platform module directly to the file reading and enumeration category of the UNSAFE_IMPORTS set.

# Patched implementation in fickling/fickle.py
@@ -140,6 +140,7 @@
         # File reading/enumeration
         "fileinput",
         "glob",
+        "platform",
         # Code compilation (writes .pyc files)
         "compileall",
         "py_compile",

While this patch successfully mitigates the specific bypass utilizing the platform module, it leaves the underlying architectural weakness unresolved. Maintaining a comprehensive denylist of all potentially dangerous Python standard library functions is error-prone, leaving the system vulnerable to future bypasses utilizing other unlisted internal module sinks.

Exploitation

Exploitation requires an attacker to construct a custom pickle file utilizing specific opcode sequences to bypass the analyzer. The attacker targets a system pipeline that utilizes fickling.analysis.check_safety() to gate the deserialization of untrusted model files or serialized Python objects.

The attacker generates a payload leveraging the GLOBAL opcode to resolve platform._syscmd_file. The payload then pushes a target file path, such as /etc/passwd, onto the stack. The REDUCE opcode is subsequently utilized to apply the target path argument to the resolved function.

payload = Pickled([
    Proto(4),
    ShortBinUnicode("platform"),
    ShortBinUnicode("_syscmd_file"),
    StackGlobal(),
    ShortBinUnicode("/etc/passwd"),
    TupleOne(),
    Reduce(),
    Stop(),
])

When processed by Fickling, the check_safety(payload) function evaluates the opcode stream, finds no matches in UNSAFE_IMPORTS, and returns Severity.LIKELY_SAFE with zero identified issues. The target application then executes pickle.loads(), causing the Python runtime to execute the underlying system command.

Impact Assessment

The primary impact of this vulnerability is the execution of unauthorized system commands and arbitrary file reads within the context of the deserializing application. Because the payload bypasses the security analyzer entirely, the malicious actions occur directly during the pickle.loads() operation on the host system.

The platform._syscmd_file function restricts execution to the system file command, preventing direct arbitrary shell command execution. The underlying subprocess.check_output call does not utilize shell=True, mitigating direct command injection via shell metacharacters. However, the attacker fully controls the target path argument passed to the utility.

This constrained execution environment allows an attacker to probe the local filesystem for file existence, read file metadata, and extract partial file contents via the output of the file command. Furthermore, utilizing platform.libc_ver(file) enables comprehensive arbitrary file read capabilities, allowing the exfiltration of sensitive configuration files, credentials, or proprietary machine learning model data.

Remediation

Organizations utilizing Fickling for pickle validation must immediately upgrade to version 0.1.10. This release incorporates the updated UNSAFE_IMPORTS list that explicitly flags the platform module as a dangerous import, successfully blocking the known exploitation vectors.

Security teams should scan historical pickle files and machine learning models for evidence of exploitation. Detection mechanisms should utilize binary grep utilities or YARA rules to search for the strings platform, _syscmd_file, and libc_ver within serialized .pkl and .pth files. Any files containing these byte sequences must be quarantined and investigated.

Developers implementing deserialization safety checks should transition away from denylist-based validation architectures. A robust implementation requires a strict allowlist approach, explicitly permitting only known-safe data structures and internal primitive modules required for operation. Relying on an exclusion list for the expansive Python standard library guarantees future parser bypass vulnerabilities.

Official Patches

Trail of BitsRelease v0.1.10 containing the security fix

Fix Analysis (1)

Technical Appendix

CVSS Score
7.5/ 10

Affected Systems

Machine Learning Model PipelinesSystems validating untrusted Python pickle files using Fickling <= 0.1.9

Affected Versions Detail

Product
Affected Versions
Fixed Version
fickling
Trail of Bits
<= 0.1.90.1.10
AttributeDetail
CWECWE-184: Incomplete List of Disallowed Inputs
Attack VectorLocal/Remote via Malicious File Upload
ImpactSecurity Bypass, Arbitrary File Read, Restricted RCE
Exploit StatusProof of Concept Available
CVSS7.5 (High)
Authentication RequiredNone

MITRE ATT&CK Mapping

T1190Exploit Public-Facing Application
Initial Access
T1059.006Command and Scripting Interpreter: Python
Execution
CWE-184
Incomplete List of Disallowed Inputs

The software uses a denylist to restrict potentially dangerous inputs, but the list is incomplete, allowing attackers to supply unsupported inputs that perform malicious actions.

Known Exploits & Detection

SynScanProof of concept demonstrating bypass utilizing GLOBAL and REDUCE opcodes to invoke platform._syscmd_file

Vulnerability Timeline

Vulnerability reported by SynScan/Trail of Bits research
2026-03-04
Patch released in version 0.1.10
2026-03-13

References & Sources

  • [1]GitHub Advisory: GHSA-5CXW-W2XG-2M8H
  • [2]Fix Commit 351ed4d
  • [3]Fickling Release v0.1.10
  • [4]Related Advisory (uuid/_osx_support)
  • [5]Technical Assessment: SynScan
Related Vulnerabilities
GHSA-5hwf-rc88-82xm

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.