You need to agree to share your contact information to access this model

This repository is publicly accessible, but you have to accept the conditions to access its files and content.

Log in or Sign Up to review the conditions and access this model content.

YAML Metadata Warning:empty or missing yaml metadata in repo card

Check out the documentation for more information.

PoC: .msgpack model file β†’ ACE via msgpack-numpy, bypassing modelaudit

Format: MessagePack (.msgpack) Impact: Arbitrary code execution on model load, undetected by Protect AI modelaudit. Payload in this repo is benign β€” it writes a marker file to the temp dir and prints a warning. Nothing destructive. For responsible-disclosure demonstration only.

Files

  • poc_flax_checkpoint.msgpack β€” a .msgpack file shaped like a normal Flax train-state (step, params, opt_state) with one malicious numpy object-array leaf.
  • build_poc.py β€” reproducible builder for the file above.
  • verify_poc.py β€” runs the two-step reproduction (scan β†’ load).

TL;DR

The file below passes modelaudit with 100% success / "No security issues detected", but executes code the moment it is loaded through msgpack-numpy β€” the standard way numpy arrays are (de)serialized over MessagePack.

Root cause

msgpack-numpy's decode() is installed as msgpack's object_hook (via msgpack_numpy.patch() or its load/unpackb). For a map with nd=True and kind=b'O' (numpy object dtype), it calls:

# msgpack_numpy.py
elif b'kind' in obj and obj[b'kind'] == b'O':
    return pickle.loads(obj[b'data'])     # <-- attacker-controlled bytes

Every byte of that trigger β€” nd, kind, and the pickle in data β€” comes straight from the file. A standard __reduce__ payload therefore yields code execution on load.

Why modelaudit misses it

modelaudit ships a flax_msgpack_scanner. It does look for pickle threats, but only with contiguous source-level string regexes (__reduce__, os\.system, subprocess, pickle\.loads, …). Pickle serializes a callable as tokenized opcodes, so os.system is stored as the GLOBAL posix + system as two separate length-prefixed strings β€” the contiguous substring os.system never appears, and posix is not in the pattern list. The scanner also never routes the object-array data blob to the real pickle-opcode analyzer that modelaudit already ships (pickle_scanner).

Contrast (same __reduce__ payload):

  • as a standalone .pkl β†’ modelaudit flags CRITICAL: "REDUCE opcode invoking dangerous global: posix.system".
  • wrapped in a msgpack object-array leaf β†’ 100% clean.

The capability exists; it is simply not applied to the object-array branch.

Reproduction

pip install msgpack msgpack-numpy numpy modelaudit
python3 verify_poc.py

Expected:

STEP 1  modelaudit scan  -> βœ… No security issues detected
STEP 2  load via msgpack_numpy -> attacker code executed (marker file written)
RESULT: scanner-clean=True  code-execution=True  => BYPASS + ACE CONFIRMED

To rebuild the file from scratch: python3 build_poc.py.

Affected versions (as tested)

msgpack-numpy==0.4.8 (latest), msgpack==1.2.1, numpy==2.4.4, modelaudit==0.2.49.

Suggested remediation

  • modelaudit: in flax_msgpack_scanner, decode kind==b'O' object-array data blobs and hand them to the existing pickle-opcode analyzer (pickle_scanner) instead of relying on contiguous string regexes; flag any .msgpack that embeds a numpy object array.
  • msgpack-numpy: gate the pickle.loads object-array branch behind an explicit opt-in (e.g. allow_pickle=False by default), mirroring numpy.load.
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