ModelScan Systemic Denylist Gap β€” 20 Bypass Vectors

Summary

ProtectAI ModelScan v0.8.8 has a systemic gap in its pickle denylist. 20 Python stdlib modules can be used to bypass detection, including 3 CRITICAL (full arbitrary code execution), 5 HIGH (native code / module loading), and 5 MEDIUM (network exposure / code compilation) severity bypasses.

Root Cause

ModelScan uses a denylist approach to detect malicious pickle operations. The denylist covers well-known dangerous modules (os, subprocess, builtins, shutil, sys, etc.) but misses many stdlib modules that provide equivalent code execution capabilities through indirect paths.

CRITICAL Bypasses (Full ACE)

Module Function Mechanism Size
cProfile run() Calls exec(statement) internally ~92 bytes
profile run() Calls exec(statement) internally ~98 bytes
timeit timeit() Calls exec(statement) internally ~95 bytes

These three modules ALL internally call Python's exec() builtin on a user-supplied string, achieving full arbitrary code execution while ModelScan reports zero issues.

HIGH Bypasses (Chain to ACE)

Module Function Mechanism
ctypes.CDLL Loads arbitrary .so files β†’ native code execution
marshal.loads Deserializes Python code objects β†’ chain to execution
importlib.import_module Imports arbitrary modules β†’ chain to os/subprocess
zipimport.zipimporter Imports from ZIP archives β†’ embedded code execution
types.FunctionType Creates callable function from code object

MEDIUM Bypasses (Network / Compilation)

Module Function Mechanism
http.server.test Starts HTTP server (directory listing + file serving)
xmlrpc.server.SimpleXMLRPCServer Starts XML-RPC server
socketserver.TCPServer Starts TCP server
doctest.run_docstring_examples Executes code from docstrings
ensurepip._main Bootstraps pip β†’ can install arbitrary packages

Reproduction

pip install modelscan==0.8.8

# Scan any bypass file β€” reports NO ISSUES
modelscan -p bypass_cProfile_run.pkl

# Load the same file β€” executes RCE payload
python3 -c "import pickle; pickle.loads(open('bypass_cProfile_run.pkl','rb').read())"

Tested Against

  • ModelScan v0.8.8 (latest as of April 2026)
  • Python 3.12.3
  • Ubuntu 24.04

Impact

Any ML model distributed as .pkl, .bin, or .pt can embed these bypass payloads. Users relying on ModelScan for safety scanning will see "No issues found" while the model achieves full arbitrary code execution on load.

Fix

The denylist approach is fundamentally insufficient. Recommended:

  1. Add ALL identified modules to denylist immediately (patch)
  2. Long-term: switch to allowlist approach (only permit known-safe pickle operations)
Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support