Skip to content

fix: add ctypes, signal, http to unsafe_globals blocklist#339

Open
scruge1 wants to merge 2 commits into
protectai:mainfrom
scruge1:fix/add-ctypes-signal-http-to-blocklist
Open

fix: add ctypes, signal, http to unsafe_globals blocklist#339
scruge1 wants to merge 2 commits into
protectai:mainfrom
scruge1:fix/add-ctypes-signal-http-to-blocklist

Conversation

@scruge1
Copy link
Copy Markdown

@scruge1 scruge1 commented Mar 23, 2026

Summary

Add ctypes, signal, http, http.client, urllib, and urllib.request to the unsafe_globals CRITICAL blocklist in settings.py.

Problem

ctypes.CDLL is not in the current blocklist. A malicious pickle/joblib/numpy file using ctypes.CDLL in __reduce__ passes modelscan with "No issues found" and achieves:

  • DLL loading with DllMain execution (single-stage RCE)
  • C runtime access via ctypes.CDLL("msvcrt").system(b"cmd") (two-stage RCE)

Confirmed end-to-end RCE:

import pickle, ctypes
class E:
    def __reduce__(self):
        return (ctypes.CDLL, ("msvcrt",))
with open("model.pkl","wb") as f: pickle.dump(E(), f)
# modelscan -p model.pkl → "No issues found!"
result = pickle.loads(open("model.pkl","rb").read())
result.system(b"echo PWNED > pwned.txt")  # File created

Also confirmed bypassing on: signal.raise_signal (DoS), http.client.HTTPConnection (network exfil).

Fix

Add these modules to the CRITICAL blocklist alongside existing entries like os, subprocess, sys.

Affected Formats

Confirmed on: Pickle (.pkl), Joblib (.pkl), NumPy (.npy). Likely affects all pickle-based formats.

Related Huntr reports submitted for Pickle, Joblib, and NPY formats.

scruge1 added 2 commits March 23, 2026 22:12
ctypes.CDLL bypasses the current blocklist and enables:
- Arbitrary DLL/SO loading with DllMain execution (single-stage RCE)
- Direct C runtime access (system(), exec())
- Confirmed end-to-end RCE on pickle, joblib, and numpy formats

Also adds signal (process crash), http.client (network exfiltration),
and urllib (data exfiltration) which also bypass the current blocklist.

All confirmed passing modelscan 0.8.8 with 'No issues found'.
- 5 tests covering ctypes.CDLL, signal, urllib detection + blocklist
  regression guard + full ModelScan end-to-end scan
- Fix: add _signal to blocklist (pickle serializes signal.raise_signal
  as _signal.raise_signal on some platforms)
- Fix: change signal from ["raise_signal"] to "*" wildcard (signal
  constants like SIGTERM are also flagged as globals)
@scruge1
Copy link
Copy Markdown
Author

scruge1 commented Mar 29, 2026

Added tests and a minor fix:

Tests (5 new):

  • test_ctypes_cdll_detected — verifies ctypes.CDLL payload is flagged CRITICAL
  • test_signal_detected — verifies signal module payloads are flagged
  • test_urllib_detected — verifies urllib.request.urlopen is flagged
  • test_new_modules_in_blocklist — regression guard for all new blocklist entries
  • test_ctypes_full_modelscan — end-to-end ModelScan scan detecting ctypes.CDLL

Fix: Added _signal to blocklist (Python's pickle serializer uses the C-level _signal module name, not signal). Also changed signal from ["raise_signal"] to "*" wildcard since signal constants (SIGTERM, etc.) are also serialized as globals.

All 5 tests pass on Python 3.10.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant