From 825f043c05c148f046fe8505c39f11707f6ba024 Mon Sep 17 00:00:00 2001 From: Ashutosh0x Date: Thu, 28 May 2026 22:38:45 +0530 Subject: [PATCH] security: add importlib and marshal to _unsafe_globals blocklist importlib.import_module() can dynamically import any module at unpickle time, completely bypassing the blocklist (e.g., importing os, subprocess, etc. indirectly). marshal.loads() can deserialize arbitrary code objects from raw bytes, enabling direct code execution without triggering any module-level detection. Both modules are marked as wildcard ('*') dangerous since all their public functions pose security risks when invoked during deserialization. Includes test pickle files and test assertions for both bypass vectors. --- src/picklescan/scanner.py | 2 ++ tests/data2/importlib_bypass.pkl | Bin 0 -> 51 bytes tests/data2/marshal_bypass.pkl | Bin 0 -> 141 bytes tests/test_scanner.py | 4 ++++ 4 files changed, 6 insertions(+) create mode 100644 tests/data2/importlib_bypass.pkl create mode 100644 tests/data2/marshal_bypass.pkl diff --git a/src/picklescan/scanner.py b/src/picklescan/scanner.py index 084d0d9..47824a2 100644 --- a/src/picklescan/scanner.py +++ b/src/picklescan/scanner.py @@ -190,7 +190,9 @@ def __str__(self) -> str: "idlelib.pyshell": {"ModifiedInterpreter.runcode", "ModifiedInterpreter.runcommand"}, "idlelib.run": {"Executive.runcode"}, "imaplib": {"IMAP4_stream"}, # IMAP4_stream executes commands via subprocess.Popen(command, shell=True) + "importlib": "*", # importlib.import_module() can dynamically import any module, bypassing the entire blocklist "lib2to3.pgen2.grammar": {"Grammar.loads"}, + "marshal": "*", # marshal.loads() can deserialize arbitrary code objects from bytes, enabling code execution "lib2to3.pgen2.pgen": {"ParserGenerator.make_label"}, "pdb": "*", "pickle": "*", diff --git a/tests/data2/importlib_bypass.pkl b/tests/data2/importlib_bypass.pkl new file mode 100644 index 0000000000000000000000000000000000000000..e60905f37e8f837231742388fc57c761638a7145 GIT binary patch literal 51 ycmZo*nX1760X>|Vxdr(}B{`W%Q+jwI?D*XLl+v8kDU+x4Fy$9dX`K=@MGpXz9}+?U literal 0 HcmV?d00001 diff --git a/tests/data2/marshal_bypass.pkl b/tests/data2/marshal_bypass.pkl new file mode 100644 index 0000000000000000000000000000000000000000..32421d6fb21f8d48c6dd57211c75a13bb4543d72 GIT binary patch literal 141 zcmZo*ncBnv0X^)wiABX3i8)hxSab3dQ;Mfdp5mPL7%B^=n1Cz?ATH(s5~&O+49$#; z3@MDk44O<)tOezHsVRP%jJH?|iZb&`Rx%WUl!J+195%%zK*4moTO2mI`6;D2sdkJ& P$