Downloads · 30 days
0
celvexgroup/modelscan-memo-poison-poc
modelscan-memo-poison-poc is a machine learning model from celvexgroup. Use it for the machine learning task on the model card, and read the license before you ship it in a product. The card lists the license as mit.
Security research artifact. This repository hosts a benign proof-of-concept for a Protect AI modelscan detection bypass (root cause: STACKGLOBAL memo reconstruction desync). It is submitted as a coordinated huntr Mode…
Downloads · 30 days
0
Access
Public
Updated Jun 30, 2026
Repo size
57 B
Likes
0
Public
Click a slice to open those files.
.md2.6 KB · 62%
From the Hugging Face model README
Security research artifact. This repository hosts a benign proof-of-concept for a
Protect AI modelscan detection bypass (root cause: STACK_GLOBAL memo reconstruction
desync). It is submitted as a coordinated huntr Model File Vulnerability (MFV) disclosure.
The payload is benign — it only prints/writes the literal marker CELVEX-MARKER. No
destructive, networked, or harmful behaviour.
poison.pkl — a pickle that, on pickle.load(), resolves and runs the denylisted
builtins.exec("print('CELVEX-MARKER')"), yet modelscan reports No issues found.modelscan's pickle scanner (modelscan/tools/picklescanner.py::_list_globals) memoizes the
textually previous opcode's parsed value (ops[n-1][1]) when it sees MEMOIZE/PUT/BINPUT,
instead of the actual pickle-VM stack top. If the opcode immediately before the memo-put is
stack-consuming (e.g. POP), its parsed value is None, so modelscan stores memo[k]=None.
A later BINGET k then injects None into the (module, name) pair reconstructed for
STACK_GLOBAL. _build_scan_result then evaluates <denied_name> in None, raising
TypeError: argument of type 'NoneType' is not iterable, which modelscan swallows as a
scanner error and reports zero issues — while the real pickle VM happily resolves the
denylisted callable and executes the payload.
This is a distinct root cause from CVE-2025-46417 (a range() ValueError crash), though it lands
in the same "scanner error → 0 issues" outcome class.
pip install modelscan
python -c "import pickle; pickle.load(open('poison.pkl','rb'))" # prints CELVEX-MARKER (payload runs)
modelscan -p poison.pkl # => "No issues found! 🎉" (+ swallowed scanner error)
Verified against modelscan 0.8.8:
poison.pkl → pickle.load executes builtins.exec (marker fires) and modelscan -p prints No issues found! 🎉.builtins.exec without the memo-poison is correctly flagged CRITICAL.In _list_globals, key the memo to the value actually pushed onto the pickle VM stack (track stack
effects per opcode) rather than the textually previous opcode's parsed value; and in
_build_scan_result, treat a reconstructed (None, …) / (…, None) global as suspicious instead
of letting the in None comparison raise and be swallowed.