ctypes, importlib, runpy, code and multiprocessing were added the list of unsafe imports (https://github.com/trailofbits/fickling/commit/9a2b3f89bd0598b528d62c10a64c1986fcb09f66, https://github.com/trailofbits/fickling/commit/eb299b453342f1931c787bcb3bc33f3a03a173f9, https://github.com/trailofbits/fickling/commit/29d5545e74b07766892c1f0461b801afccee4f91, https://github.com/trailofbits/fickling/commit/b793563e60a5e039c5837b09d7f4f6b92e6040d1, https://github.com/trailofbits/fickling/commit/b793563e60a5e039c5837b09d7f4f6b92e6040d1).
The unsafe_imports() method in Fickling's static analyzer fails to flag several high-risk Python modules that can be used for arbitrary code execution. Malicious pickles importing these modules will not be detected as unsafe, allowing attackers to bypass Fickling's primary static safety checks.
In fickling/fickle.py lines 866-884, the unsafe_imports() method checks imported modules against a hardcoded tuple:
def unsafe_imports(self) -> Iterator[ast.Import | ast.ImportFrom]:
for node in self.properties.imports:
if node.module in (
"__builtin__", "__builtins__", "builtins", "os", "posix", "nt",
"subprocess", "sys", "builtins", "socket", "pty", "marshal", "types",
):
yield node
This list is incomplete. The following dangerous modules are NOT detected:
Since ctypes is part of the Python standard library, it also bypasses the NonStandardImports analysis.
from fickling.fickle import Pickled
from fickling.analysis import check_safety, Severity
# Pickle that imports ctypes.pythonapi (allows arbitrary code execution)
# PROTO 4, GLOBAL 'ctypes pythonapi', STOP
payload = b'\x80\x04cctypes\npythonapi\n.'
pickled = Pickled.load(payload)
results = check_safety(pickled)
print(f"Severity: {results.severity.name}")
print(f"Is safe: {results.severity == Severity.LIKELY_SAFE}")
# Output: Severity is LIKELY_SAFE or low - the ctypes import is not flagged
# A truly malicious pickle using ctypes could execute arbitrary code
Security Bypass (Confidentiality, Integrity, Availability)
An attacker can craft a malicious pickle that:
1. Imports ctypes to gain arbitrary memory access
2. Uses ctypes.pythonapi or ctypes.CDLL to execute arbitrary code
3. Passes Fickling's safety analysis as "likely safe"
4. Executes malicious code when the victim loads the pickle after trusting Fickling's verdict
This undermines the core purpose of Fickling as a pickle safety scanner.
{
"nvd_published_at": "2026-01-10T02:15:50Z",
"cwe_ids": [
"CWE-184",
"CWE-502"
],
"github_reviewed_at": "2026-01-09T21:12:00Z",
"severity": "HIGH",
"github_reviewed": true
}