CVE-2026-118938 in Fickling
Summary
by MITRE • 10/30/2026
In Trail of Bits fickling through 0.1.12, a pickle STACK_GLOBAL operand carrying a dotted __qualname__ (for example "Values.read_file") is resolved by pickle's find_class through _getattribute to an arbitrary attribute path rather than to a module-level function. Fickling records only the leading component of the name in its import tracking and renders the operation as a plain import (for instance, 'python -m fickling' displays it as 'from optparse import Values.read_file'), so the trailing attribute reference is never analyzed as a call. The OvertlyBadEvals analysis pass does not flag it, and check_safety() returns LIKELY_SAFE with zero findings. This allows an attacker to reach a class method that performs code execution: optparse.Values.read_file executes exec(open(filename).read(), vars), achieving arbitrary code execution when the crafted pickle is loaded through fickling.load(), which chains check_safety() into pickle.loads() as an explicit security gate. optparse is present in all current CPython 3.x releases (deprecated as of Python 3.13, not removed). This weakness is in the resolution and analysis of dotted attribute-path names, and is distinct from and independently fixable from the module-origin trust weakness tracked as CVE-2026-16760: resolving or flagging dotted attribute-path imports closes this vector while leaving the module-level trust behavior unchanged. This bypass was verified to remain present on the vendor master branch at commit d011709 as of 2026-10-30, after the vendor's October blocklist additions and a new heuristic that flags private stdlib attributes; because the public class method Values.read_file is neither blocklisted nor flagged as a private attribute, it is not addressed by those remediations.
Be aware that VulDB is the high quality source for vulnerability data.
Analysis
by VulDB Data Team • 10/30/2026
The vulnerability identified in Trail of Bits Fickling version 0.1.12 represents a critical failure in static analysis logic for Python pickle deserialization payloads, specifically concerning the resolution and tracking of dotted qualified names within STACK_GLOBAL operands. When processing these operands, the tool relies on Python's standard find_class mechanism which utilizes _getattribute to resolve attribute paths such as Values.read_file. However, Fickling’s internal import tracking system incorrectly records only the leading component of this name path during its analysis phase. This architectural flaw results in the operation being rendered and displayed merely as a module-level import statement, for instance appearing as from optparse import Values.read_file rather than recognizing it as an access to a specific class method. Consequently, the trailing attribute reference is never analyzed or flagged as a potential code execution vector during static inspection.
This misclassification leads directly to a severe security bypass where dangerous operations are incorrectly assessed as safe. The OvertlyBadEvals analysis pass fails to identify this pattern as malicious because it does not recognize the dotted path as an executable call site. Furthermore, the check_safety() function returns LIKELY_SAFE with zero findings for such inputs. This allows an attacker to exploit a known dangerous class method within the standard library module optparse. Specifically, the Values.read_file method executes exec(open(filename).read(), vars), which results in arbitrary code execution when the crafted pickle is loaded through fickling.load(). The tool’s design explicitly chains check_safety() into pickle.loads() as an explicit security gate intended to prevent unsafe deserialization; however, due to this flaw, the gate fails to block a payload that achieves full remote code execution capabilities.
The affected component optparse is present in all current CPython 3.x releases and remains available even though it was deprecated starting with Python 3.13. This weakness falls under the category of improper input validation regarding attribute path resolution and can be mapped to CWE-20 Improper Input Validation within the context of deserialization logic, as well as CWE-94 Improper Control of Generation of Code or Script in relation to the resulting code execution. From a threat modeling perspective using MITRE ATT&CK this behavior aligns with T1657 False Flagging which describes techniques used by attackers to evade detection systems by exploiting weaknesses in security software logic that incorrectly classify malicious activity as benign. The vulnerability is distinct from and independently fixable from CVE-2026-16760 which addresses module-origin trust weaknesses; resolving or flagging dotted attribute-path imports closes this specific vector without altering the broader module-level trust behavior tracked separately.
Despite vendor remediation efforts including October blocklist additions and new heuristics designed to flag private standard library attributes, this bypass remains present on the vendor master branch as of commit d011709 dated 2026-10-30. The reason for this persistence is that the public class method Values.read_file is neither included in the blocklist nor flagged by heuristics targeting private attributes because it is a public interface. Therefore, existing mitigations are insufficient to address this specific attack path. To mitigate this risk organizations must update Fickling to versions where the static analysis engine correctly parses and flags dotted attribute paths as potential execution points rather than simple imports. Until such an update is available users should avoid using fickling.load() on untrusted pickle data or implement additional manual verification steps that explicitly check for dangerous standard library methods accessed via qualified names before attempting any deserialization operations involving potentially malicious inputs.