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 0000000..e60905f Binary files /dev/null and b/tests/data2/importlib_bypass.pkl differ diff --git a/tests/data2/marshal_bypass.pkl b/tests/data2/marshal_bypass.pkl new file mode 100644 index 0000000..32421d6 Binary files /dev/null and b/tests/data2/marshal_bypass.pkl differ diff --git a/tests/test_scanner.py b/tests/test_scanner.py index 7e27322..4e1a9c0 100644 --- a/tests/test_scanner.py +++ b/tests/test_scanner.py @@ -458,6 +458,10 @@ def test_scan_file_path(): "GHSA-g38g-8gr9-h9xp-test.pkl", [Global("test.support.script_helper", "assert_python_ok", SafetyLevel.Dangerous)], ) + # importlib.import_module can dynamically import any module, bypassing the entire blocklist + assert_scan("importlib_bypass.pkl", [Global("importlib", "import_module", SafetyLevel.Dangerous)]) + # marshal.loads can deserialize arbitrary code objects from bytes, enabling code execution + assert_scan("marshal_bypass.pkl", [Global("marshal", "loads", SafetyLevel.Dangerous)]) def test_scan_file_path_npz():