Skip to content

Commit ee38e74

Browse files
authored
Add runpy to unsafe operators (#27)
1 parent d346153 commit ee38e74

File tree

2 files changed

+21
-3
lines changed

2 files changed

+21
-3
lines changed

src/picklescan/scanner.py

+1
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ def __str__(self) -> str:
114114
"socket": "*",
115115
"subprocess": "*",
116116
"sys": "*",
117+
"runpy": "*", # Includes runpy._run_code
117118
"operator": "attrgetter", # Ex of code execution: operator.attrgetter("system")(__import__("os"))("echo pwned")
118119
"pickle": "*",
119120
"_pickle": "*",

tests/test_scanner.py

+20-3
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import importlib
44
import io
55
import os
6+
import runpy
67
import pickle
78
import pytest
89
import requests
@@ -83,6 +84,11 @@ def __reduce__(self):
8384
return pickle.loads, (b"I12345\n.",) # Loads the value 12345
8485

8586

87+
class Malicious14:
88+
def __reduce__(self):
89+
return runpy._run_code, ("print('456')",)
90+
91+
8692
class HTTPResponse:
8793
def __init__(self, status, data=None):
8894
self.status = status
@@ -336,6 +342,9 @@ def initialize_pickle_files():
336342
initialize_pickle_file(
337343
f"{_root_path}/data/malicious13b.pkl", Malicious13(), 4
338344
) # pickle module serialized as _pickle
345+
initialize_pickle_file(
346+
f"{_root_path}/data/malicious14.pkl", Malicious14(), 4
347+
) # runpy
339348

340349
initialize_zip_file(
341350
f"{_root_path}/data/malicious1.zip",
@@ -552,6 +561,13 @@ def test_scan_file_path():
552561
scan_file_path(f"{_root_path}/data/bad_pytorch.pt"), bad_pytorch
553562
)
554563

564+
malicious14 = ScanResult(
565+
[Global("runpy", "_run_code", SafetyLevel.Dangerous)], 1, 1, 1
566+
)
567+
compare_scan_results(
568+
scan_file_path(f"{_root_path}/data/malicious14.pkl"), malicious14
569+
)
570+
555571

556572
def test_scan_directory_path():
557573
sr = ScanResult(
@@ -578,6 +594,7 @@ def test_scan_directory_path():
578594
Global("requests.api", "get", SafetyLevel.Dangerous),
579595
Global("builtins", "eval", SafetyLevel.Dangerous),
580596
Global("builtins", "eval", SafetyLevel.Dangerous),
597+
Global("runpy", "_run_code", SafetyLevel.Dangerous),
581598
Global("socket", "create_connection", SafetyLevel.Dangerous),
582599
Global("collections", "OrderedDict", SafetyLevel.Innocuous),
583600
Global("torch._utils", "_rebuild_tensor_v2", SafetyLevel.Innocuous),
@@ -594,9 +611,9 @@ def test_scan_directory_path():
594611
Global("_pickle", "loads", SafetyLevel.Dangerous),
595612
Global("_codecs", "encode", SafetyLevel.Suspicious),
596613
],
597-
scanned_files=27,
598-
issues_count=25,
599-
infected_files=22,
614+
scanned_files=28,
615+
issues_count=26,
616+
infected_files=23,
600617
scan_err=True,
601618
)
602619
compare_scan_results(scan_directory_path(f"{_root_path}/data/"), sr)

0 commit comments

Comments
 (0)