MLOps Platforms
Isometric illustration of a warning-marked shield on a circuit-traced platform of linked cubes, representing ML model supply chain attack paths
ML Security

ML Model Supply Chain Attacks: Vectors and Defenses

ML model supply chain attacks use serialization flaws, namespace hijacking, and hub poisoning to run code when you load a model. Here is what stops them.

By MLOps Platforms Editorial · · Updated · 5 min read

ML model supply chain attacks are not theoretical. In early 2025, ReversingLabs researchers found two production-ready malicious models on Hugging Face that connected to attacker-controlled servers via reverse shell — and both evaded the platform’s primary scanning tool. The defensive answer starts in the registry: model registry patterns that hold in production covers the provenance fields worth enforcing. The attack vector was not the model architecture. It was a .pkl file loaded at inference time.

That incident is one data point in a larger pattern. As model hubs become the dependency managers of the ML world — functioning the same way npm or PyPI do for software — the attack surface has grown proportionally. The question for platform engineers is not whether ml model supply chain attacks happen. It is which attack vector will hit your pipeline first.

The Attack Surface Map

ML supply chain attacks target the trust chain between a model’s origin and its execution in your environment. The main exposure points:

Model serialization files. The dominant format for PyTorch weights is pickle. Python’s pickle module is inherently unsafe: it executes arbitrary Python code during deserialization. Loading an untrusted .pkl file is equivalent to running untrusted code. There is no sandboxing at the deserialization layer.

Model hub namespaces. Hub platforms like Hugging Face resolve models by org/model-name. If an organization deletes its account, the namespace becomes available for re-registration. An attacker can claim the abandoned name, upload a malicious model, and silently serve it to any pipeline that pulls by name rather than digest.

Framework and library dependencies. ML training stacks pull in dozens of packages: transformers, diffusers, timm, sentence-transformers, peft. Each is a dependency that can be compromised upstream, the same way a PyPI or npm package can carry a typosquat or a compromised maintainer’s release.

Training data and dataset loading scripts. Some Hugging Face datasets ship with executable Python loading scripts. A poisoned dataset loading script runs in the training environment before any model weights are involved — earlier and often less scrutinized than model files.

The Pickle Serialization Problem

The arXiv paper 2410.04490 from October 2024 provides the clearest large-scale measurement of this vector on Hugging Face. Researchers found the platform home to a “wide range of potentially vulnerable models” using unsafe serialization, demonstrating that models can be exploited via object injection and shared across the hub without triggering platform-level defenses.

The nullifAI campaign documented by ReversingLabs in early 2025 shows exactly how that exploitation plays out. The attacker technique had three components:

  1. Compression format substitution. The malicious models were compressed with 7z instead of PyTorch’s default ZIP format. Hugging Face’s Picklescan tool validates files before interpreting opcodes, and could not parse the 7z container.
  2. Deliberate corruption after injection. Attackers injected the malicious payload at the beginning of the pickle stream, then deliberately corrupted the file structure afterward. Picklescan, using blacklist-based detection, failed on the corrupted file and returned no alert.
  3. Early execution. Because pickle opcodes are interpreted sequentially during load, the malicious code — a platform-aware reverse shell connecting to a hardcoded IP — executed before the corruption point was reached.

The 2409.09368 paper (“Models Are Codes”) provides complementary breadth data. Scanning over 705,000 Hugging Face models and 176,000 datasets over a three-month window, the researchers identified 91 malicious models and 9 malicious dataset loading scripts. Attack types included reverse shell activation, browser credential theft, and host reconnaissance. Existing scanning tools — Fickling, ModelScan, Picklescan — had measurable detection gaps against the variants found.

Namespace Hijacking and Model Squatting

Unit 42’s research on model namespace reuse describes a different but equally dangerous attack class. The mechanism: when a Hugging Face account is deleted, its username namespace becomes available. Any pipeline that pulls a model by name — rather than by cryptographic digest — becomes vulnerable.

The research team validated the attack across major cloud AI platforms. On Google Vertex AI, they demonstrated remote code execution on a deployed endpoint. On Microsoft Azure AI Foundry, they obtained endpoint access and environment permissions. They also found thousands of open-source repositories containing hardcoded model references with no hash pinning, creating a large ambient attack surface that persists for as long as those repositories are active.

The MITRE ATLAS framework catalogs this class of threat under AI Supply Chain Compromise. ATLAS is the AI-specific counterpart to ATT&CK, covering adversarial tactics from model poisoning through infrastructure compromise. The Spring 2025 release added 19 new techniques, including explicit coverage of supply chain attacks against model serving infrastructure. Our model serving comparison covers how much of that surface each managed platform takes off your hands.

What Actually Stops This

The controls below stop the attack at the artifact. The controls that stop it at the endpoint — least-privilege inference, output handling, and adversarial monitoring — are the subject of secure ML model deployment best practices, and both sets belong in the same pipeline rather than in competition.

Switch serialization formats. The Hugging Face safetensors format stores only tensor data — no executable code, no pickle opcodes. For any model you control, migrating weights to safetensors eliminates the serialization attack vector entirely. When loading third-party models, prefer repositories that provide safetensors variants.

from safetensors.torch import load_file

# Load weights without executing arbitrary Python code
state_dict = load_file("model.safetensors")
model.load_state_dict(state_dict)

Pin by digest, not by name. In automated pipelines, never resolve models by name alone. Pull the SHA256 digest of the model files at review time, commit the digest to your pipeline config, and verify at load time. This defeats namespace hijacking: a new model uploaded under the same name will have a different digest.

import hashlib, pathlib

EXPECTED_SHA256 = "a3f9c..."  # pinned at review time

def verified_load(path: str) -> bytes:
    data = pathlib.Path(path).read_bytes()
    digest = hashlib.sha256(data).hexdigest()
    if digest != EXPECTED_SHA256:
        raise ValueError(f"Digest mismatch: got {digest}")
    return data

Gate on a model registry with lineage tracking. MLflow’s Model Registry records the source run, artifact hash, and transition history for every registered version. Gating serving on registry status — rather than pulling directly from a hub — adds an audit log and a human approval step between external download and production deployment. For observability into what model artifacts are actually running in production, the monitoring approaches covered at sentryml.com apply directly here: tracking which model version is live, and when it changed, is table stakes for detecting substitution attacks.

Treat dataset loading scripts as untrusted code. When using Hugging Face datasets, the trust_remote_code=True parameter should be an explicit, reviewed decision — not a default. Script-based loaders should run in an isolated environment, not in the same process as your training job.

Monitor hub namespaces for your dependencies. For models you pin and deploy, set up alerts if the upstream repository changes ownership or is deleted. A deletion event is the precondition for namespace reuse. Catching it before your next pipeline run gives you time to respond.

The broader adversarial ML risk — including model poisoning and backdoor injection during training — connects directly to the serialization surface documented here. aisec.blog covers those training-time attack vectors in detail.

Sources

  1. A Large-Scale Exploit Instrumentation Study of AI/ML Supply Chain Attacks in Hugging Face Models (arXiv 2410.04490)
  2. nullifAI: Malicious ML models discovered on Hugging Face — ReversingLabs
  3. Model Namespace Reuse: An AI Supply-Chain Attack Exploiting Model Name Trust — Unit 42
  4. Models Are Codes: Towards Measuring Malicious Code Poisoning Attacks on Pre-trained Model Hubs (arXiv 2409.09368)
#supply-chain-security #model-security #mlops #pickle#huggingface
Subscribe

MLOps Platforms — in your inbox

Honest reviews and comparisons of MLOps platforms. Sent only when there is something worth sending.

No spam. Unsubscribe anytime.

Related