CVE-2025-67748: 
Python vulnerability analysis and mitigation

Overview

CVE-2025-67748 is a security bypass vulnerability in Trail of Bits' Fickling, a Python pickle decompiler and static analyzer, that allows crafted malicious pickle files to evade safety detection and achieve arbitrary code execution. The root cause is the pty module being absent from Fickling's blocklist of unsafe module imports, causing pickle files leveraging pty.spawn() to be incorrectly classified as LIKELY_SAFE. All versions prior to 0.1.6 are affected. The vulnerability was disclosed on December 15, 2025, with a CVSS v3.1 score of 7.8 (High) and a CVSS v4.0 score of 7.1 (High) (GitHub Advisory, GHSA Advisory).

Technical details

The vulnerability is classified under CWE-184 (Incomplete List of Disallowed Inputs), CWE-502 (Deserialization of Untrusted Data), and CWE-94 (Improper Control of Generation of Code). Fickling's safety analysis relies on heuristics including detection of "unused variables" left on the pickle VM stack after execution of dangerous opcodes (e.g., REDUCE, OBJ, INST). An attacker can bypass this heuristic by appending a BUILD opcode after the malicious REDUCE call, which effectively "uses" the leftover stack variable by adding a __setstate__ to it, causing Fickling to classify the file as safe. Additionally, because pty was not in the unsafe imports blocklist, pickle files calling pty.spawn() were not flagged regardless of the unused-variable heuristic. A public proof-of-concept disassembly demonstrating the bypass via pty.spawn('id') with appended MEMOIZE and BUILD opcodes is included in the advisory (GHSA Advisory, PR #108).

Impact

Successful exploitation results in arbitrary code execution on the system of any user or automated pipeline that deserializes a pickle file after Fickling has incorrectly vetted it as safe. The impact spans full confidentiality, integrity, and availability compromise of the affected system, as the attacker-controlled code runs with the privileges of the deserializing process. This is particularly relevant in AI/ML pipelines that use Fickling to screen model files (e.g., PyTorch .pth files) before loading, where a malicious model could be silently executed (GitHub Advisory, GHSA Advisory).

Exploitability

A proof-of-concept exploit is publicly available in the GitHub security advisory, demonstrating the bypass using pty.spawn() with appended BUILD opcodes to evade Fickling's detection (GHSA Advisory). There is no evidence of in-the-wild exploitation at this time, and the vulnerability is not listed in the CISA Known Exploited Vulnerabilities (KEV) catalog. The EPSS score is approximately 0.024–0.028%, placing it in the 8th percentile for exploitation likelihood. Exploitation requires user interaction — a victim must deserialize the crafted pickle file — and the attack vector is local, limiting the attack surface to scenarios where untrusted pickle files are distributed and processed through Fickling-vetted pipelines.

Exploitation steps

  1. Craft the malicious pickle payload: Create a pickle file that calls pty.spawn() with a desired command (e.g., id or a reverse shell). Use Python's pickle and pickletools modules to construct the bytecode, leveraging STACK_GLOBAL to reference pty.spawn, TUPLE1 to wrap the argument, and REDUCE to invoke it.
  2. Bypass the unused-variable heuristic: Append a MEMOIZE opcode after REDUCE to store the result, then add a SHORT_BINUNICODE string (e.g., 'gottem') followed by a BUILD opcode. This causes Fickling to treat the result of REDUCE as "used," preventing the unused-variable flag from triggering.
  3. Bypass the blocklist check: Because pty was absent from Fickling's unsafe imports blocklist in versions ≤ 0.1.5, the import itself does not trigger a safety alert, resulting in a LIKELY_SAFE classification.
  4. Deliver the file to the target: Distribute the crafted .pkl file through a model repository, file share, or any channel where the victim's system uses Fickling to vet pickle files before deserialization.
  5. Trigger deserialization: When the victim (or an automated pipeline) deserializes the file — believing it to be safe based on Fickling's LIKELY_SAFE verdict — pty.spawn() executes the embedded command with the privileges of the deserializing process, achieving arbitrary code execution (GHSA Advisory, PR #108).

Indicators of compromise

  • File System: Presence of pickle files (.pkl, .pth, or similar) containing pty and spawn strings in their binary content; unexpected files created by the deserializing process (e.g., web shells, scripts, or data exfiltration artifacts).
  • Process: Unusual child processes spawned by a Python interpreter during model loading or pickle deserialization (e.g., /bin/sh, bash, id, curl, wget, or interactive terminal processes); processes with pty in their invocation context.
  • Logs: Python application logs showing Fickling returning LIKELY_SAFE for files that subsequently cause unexpected process spawning; audit logs recording execution of system commands immediately following pickle deserialization events.
  • Network: Unexpected outbound connections from the deserializing host following pickle file loading, potentially indicating reverse shell or data exfiltration activity.

Mitigation and workarounds

Upgrade Fickling to version 0.1.6 or later, which adds pty to the blocklist of unsafe module imports, preventing pty.spawn()-based payloads from being classified as safe. The fix was implemented via pull request #187 and released on December 15, 2025 (PR #187, GitHub Advisory). As an interim workaround, avoid deserializing any pickle files from untrusted sources regardless of Fickling's verdict, and consider supplementing Fickling with additional validation layers or switching to safer serialization formats (e.g., JSON, Protocol Buffers) where feasible. Organizations using Fickling in AI/ML pipelines to screen model files should treat all externally sourced pickle files as untrusted until the patch is applied.

Community reactions

Trail of Bits, the maintainer of Fickling, promptly acknowledged and fixed the vulnerability on the same day it was disclosed (December 15, 2025), merging PR #187 and publishing the security advisory under GHSA-r7v6-mfhq-g3m2 (GHSA Advisory). The vulnerability was reported by security researchers ajohnston9 and 0x00nier, with the initial pty blocklist gap first identified in PR #108 as early as May 2024 but not merged until the formal advisory triggered PR #187 (PR #108). Coverage appeared on security aggregators including INCIBE-CERT, VulDB, and InfinitSec shortly after disclosure.

Additional resources


Source: This report was generated using AI

Related Python vulnerabilities:

CVE ID

Severity

Score

Technologies

Component name

CISA KEV exploit

Has fix

Published date

GHSA-v2f8-6655-7grjCRITICAL10
  • Python logoPython
  • vibe-trading-ai
NoYesOct 02, 2026
CVE-2026-105782HIGH7.5
  • Python logoPython
  • scrapy
NoYesOct 06, 2026
GHSA-v853-p72q-4cfwHIGH7.5
  • Python logoPython
  • quart
NoYesOct 05, 2026
CVE-2026-105751MEDIUM6.9
  • Python logoPython
  • docling
NoYesOct 05, 2026
CVE-2026-105750MEDIUM5.9
  • Python logoPython
  • docling
NoYesOct 05, 2026

Free Vulnerability Assessment

Benchmark your Cloud Security Posture

Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.

Request assessment

Get a personalized demo

Ready to see Wiz in action?

"Best User Experience I have ever seen, provides full visibility to cloud workloads."
David EstlickCISO
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
Adam FletcherChief Security Officer
"We know that if Wiz identifies something as critical, it actually is."
Greg PoniatowskiHead of Threat and Vulnerability Management