Mar 13, 2026·6 min read·33 visits
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.
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.
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.
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 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.
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.
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.
| Product | Affected Versions | Fixed Version |
|---|---|---|
fickling Trail of Bits | <= 0.1.9 | 0.1.10 |
| Attribute | Detail |
|---|---|
| CWE | CWE-184: Incomplete List of Disallowed Inputs |
| Attack Vector | Local/Remote via Malicious File Upload |
| Impact | Security Bypass, Arbitrary File Read, Restricted RCE |
| Exploit Status | Proof of Concept Available |
| CVSS | 7.5 (High) |
| Authentication Required | None |
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.
CVE-2026-115895 is a high-severity code injection vulnerability (CWE-94) in the happy-dom npm package prior to version 21.0.4. The vulnerability exists within the ECMAScriptModuleCompiler component, which transforms ECMAScript module syntax into executable Node.js functions when JavaScript evaluation is enabled. Due to an incomplete fix for CVE-2026-33943, the compiler failed to validate local named import aliases against legal JavaScript identifier rules. Attackers supplying crafted module imports—specifically utilizing destructuring default initializers alongside JSON module attributes—can inject arbitrary JavaScript expressions directly into the host Node.js runtime context.
An improper input validation and authorization bypass vulnerability exists in the LangGraph storage layer affecting langgraph, langgraph-checkpoint-postgres, and langgraph-checkpoint-sqlite. Because relational store implementations serialize namespace tuples into dot-delimited strings without validating labels on read, search, delete, and batch operations, an attacker who controls a namespace label can inject periods (.) to traverse namespace boundaries and access, modify, or delete data belonging to other namespaces.
CVE-2026-115886 (GHSA-2wqp-q3c6-ccj5) is a Server-Side Request Forgery (SSRF) and Unsafe Reflection vulnerability in MLflow versions 3.12.0rc0 prior to 3.17.0. Unauthenticated REST API endpoints accept serialized third-party scorer JSON payloads that are dynamically deserialized and reflectively instantiated without sanitizing constructor keyword arguments. When optional dependencies such as trulens and trulens-providers-litellm are installed, attackers can inject egress-steering arguments into the scorer payload, forcing the MLflow server to dispatch outbound HTTP requests to arbitrary internal destinations or cloud metadata services.
CVE-2026-113872 (GHSA-q7qp-rjg7-q26m) is a high-severity denial-of-service vulnerability affecting the multer multipart/form-data upload middleware for Node.js and Express in versions 2.0.0 through 2.4.0. When an endpoint is configured to accept multiple files using an asynchronous fileFilter callback, a crafted, truncated multipart HTTP request can trigger an unhandled error event on the underlying busboy stream parser after request teardown has already completed. Because all error listeners are stripped during teardown, Node.js treats the resulting error event as an uncaught exception and immediately terminates the server process.
CVE-2026-115897 (also tracked as GHSA-m5mm-p8h7-m29v and aliased as CVE-2026-115754) is a Cross-Site Scripting (XSS) vulnerability in the Yahoo serialize-javascript npm package prior to version 7.1.3. The flaw exists in the regular expression used by escapeFunctionBody() to neutralize HTML script closing tags within serialized JavaScript functions. Because function bodies are sanitized in isolation before structural formatting is applied, a function whose string representation terminates directly with the sequence '</script' bypasses the positive lookahead check. When combined with serialization formatting options that introduce whitespace delimiters and a subsequent property that supplies a closing bracket, an attacker can prematurely terminate an enclosing HTML <script> block and inject arbitrary HTML or JavaScript into the rendered document.
CVE-2026-109841 is a Subresource Integrity (SRI) verification bypass vulnerability in undici, the official HTTP/1.1 and HTTP/2 client library for Node.js that powers the global fetch() implementation. The flaw stems from improper handling of case sensitivity (CWE-178) when validating cryptographic hash algorithm tokens within SRI metadata. Because undici compared incoming algorithm identifiers against a strictly lowercase set without prior ASCII-lowercase normalization, valid uppercase or mixed-case tokens such as SHA256- or Sha384- were treated as unrecognized algorithms and discarded. Under SRI forward-compatibility rules, discarding all provided tokens results in an empty integrity list, causing undici to fail open and accept tampered HTTP response bodies without cryptographic verification.