genai
SECURITY LAB
IncidentsSupply chain

nullifAI: Broken Pickles That Slipped Past Model Scanning

High severityFebruary 2025LLM04: Supply Chain
Status: Hugging Face removed the models within ~24h; Picklescan was updated to detect broken-pickle threats
On this page

Attackers don't just hide from scanners — they craft payloads specifically to break them.

WhenFebruary 2025
TargetHugging Face model hub (Picklescan)
ResearcherReversingLabs
TechniqueBroken/non-standard pickle to evade scanning, opcodes run early
ImpactReverse shell on load while bypassing detection
Attack flow
  1. 1An attacker stores a malicious model as a deliberately broken, 7z-compressed pickle
  2. 2The scanner can't parse it and fails to flag it; torch.load errors out
  3. 3But the malicious opcodes run first — a reverse shell fires before the file 'breaks'

What happened

In February 2025, ReversingLabs found malicious Hugging Face models that carried a reverse-shell payload but were stored as PyTorch pickles compressed with 7z instead of the default ZIP. As a result torch.load couldn't open them and Hugging Face's Picklescan failed to flag them — yet the malicious opcodes, placed early in the stream, still executed during deserialisation before the “broken” file errored out. They named the evasion “nullifAI.”

How the attack worked

The attacker exploited a gap between the scanner's parser and the deserialiser: the file looked un-scannable/invalid to the tool, but the runtime still ran the payload's opcodes before hitting the error.

Root cause

Relying on a single scanner as the control, against an unsafe format an attacker can deliberately malform to slip past it.

What a control would have caught

Defence in depth — sandboxed loading and preferring safetensors — contains the payload even when a scanner is evaded, which signature-only detection cannot.

How to prevent it

  • Don't trust a scanner as your only gate; assume evasion.
  • Prefer safetensors; sandbox any pickle-based load.
  • Update detectors for malformed inputs (Picklescan was patched here).

Feel it yourselfThe replay lab loads a backdoored model file — the malicious-model class this evasion belongs to.

FAQ

How did it evade detection?

The models were stored as pickles compressed with 7z instead of the default ZIP, so torch.load couldn't open them and Picklescan failed to flag them — but the malicious opcodes, placed early in the stream, still ran during deserialisation before the file errored out.

What's the broader lesson?

Scanner-based defences are necessary but not sufficient: attackers specifically craft payloads to defeat known scanners. Defence in depth (sandboxed loading, safetensors) matters.

Was it fixed?

Hugging Face removed the models within about a day of notification, and Picklescan was updated to detect threats in corrupted pickle files.

Replay this attack
Load a backdoored model file that triggers attacker behaviour — the malicious-model supply-chain class.
Open the live lab
Runs as a live, sandboxed lab. Sign-in required — this replay is a Pro lab. Recreates the attack class, not this exact branded bot.