Skip to content

Commit a01c58d

Browse files
authored
1 parent 323bd00 commit a01c58d

File tree

7 files changed

+23
-5
lines changed

7 files changed

+23
-5
lines changed

requirements.txt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
twine==4.0.1
22
flake8==5.0.4
3-
pytest==7.1.3
4-
pytest-cov==3.0.0
3+
pytest==8.3.5
4+
pytest-cov==6.0.0
55
requests==2.32.5
6-
aiohttp==3.13.2
7-
black==22.8.0
6+
aiohttp==3.13.3
7+
black==24.10.0
88
numpy>1.24.0,<2.0.0
99
py7zr==0.22.0

setup.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[metadata]
22
name = picklescan
3-
version = 0.0.34
3+
version = 0.0.35
44
author = Matthieu Maitre
55
author_email = mmaitre314@users.noreply.github.com
66
description = Security scanner detecting Python Pickle files performing suspicious actions

src/picklescan/scanner.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ def __str__(self) -> str:
125125
"ctypes": "*", # Foreign function interface, can load DLLs, call C functions, manipulate raw memory
126126
"functools": "partial", # functools.partial(os.system, "echo pwned")
127127
"httplib": "*", # Includes http.client.HTTPSConnection()
128+
"_io": {"FileIO"}, # io.FileIO is stored as _io.FileIO, can read arbitrary files bypassing builtins.open blocklist
128129
"numpy.f2py": "*", # Multiple unsafe functions (e.g., getlincoef, _eval_length) that call eval on arbitrary strings
129130
"numpy.testing._private.utils": "*", # runstring() in this module is a synonym for exec()
130131
"nt": "*", # Alias for 'os' on Windows. Includes os.system()
@@ -181,6 +182,7 @@ def __str__(self) -> str:
181182
"basichandlers"
182183
}, # allows storing a pickle inside a pickle (if this has valid use cases, scan the input bytes instead of flagging the global)
183184
"trace": {"Trace.run", "Trace.runctx"},
185+
"urllib.request": "*", # urllib.request.urlopen can be used for SSRF and data exfiltration
184186
"venv": "*",
185187
"webbrowser": "*", # Includes webbrowser.open()
186188
}

tests/data2/io_FileIO.pkl

50 Bytes
Binary file not shown.
71 Bytes
Binary file not shown.

tests/init_data_files.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,18 @@ def reduce_GHSA_r8g5_cgf2_4m4m():
355355
return getlincoef, (_payload, [])
356356

357357

358+
def reduce_io_FileIO():
359+
import io
360+
361+
return io.FileIO, ("/etc/hosts", "r")
362+
363+
364+
def reduce_urllib_request_urlopen():
365+
import urllib.request
366+
367+
return urllib.request.urlopen, ("https://example.invalid",)
368+
369+
358370
def initialize_pickle_file(path: str, obj: Any, version: int):
359371
if os.path.exists(path):
360372
print(f"File {path} already exists, skipping initialization.")
@@ -781,6 +793,8 @@ def initialize_pickle_files():
781793
initialize_pickle_file_from_reduce("GHSA-84r2-jw7c-4r5q.pkl", reduce_GHSA_84r2_jw7c_4r5q)
782794
initialize_pickle_file_from_reduce("GHSA-vqmv-47xg-9wpr.pkl", reduce_GHSA_vqmv_47xg_9wpr)
783795
initialize_pickle_file_from_reduce("GHSA-r8g5-cgf2-4m4m.pkl", reduce_GHSA_r8g5_cgf2_4m4m)
796+
initialize_pickle_file_from_reduce("io_FileIO.pkl", reduce_io_FileIO)
797+
initialize_pickle_file_from_reduce("urllib_request_urlopen.pkl", reduce_urllib_request_urlopen)
784798

785799

786800
def initialize_numpy_files():

tests/test_scanner.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,8 @@ def test_scan_file_path():
393393
"GHSA-46h3-79wf-xr6c.pkl",
394394
[Global("_operator", "attrgetter", SafetyLevel.Dangerous), Global("builtins", "__import__", SafetyLevel.Suspicious)],
395395
)
396+
assert_scan("io_FileIO.pkl", [Global("_io", "FileIO", SafetyLevel.Dangerous)])
397+
assert_scan("urllib_request_urlopen.pkl", [Global("urllib.request", "urlopen", SafetyLevel.Dangerous)])
396398

397399

398400
def test_scan_file_path_npz():

0 commit comments

Comments
 (0)