Articles / Supply Chain Risk in the LLM Stack
OWASP LLM03 · Supply Chain

Supply Chain Risk in the LLM Stack

Almost nobody trains a frontier model from scratch. What ships to production is assembled: a pretrained base pulled from a public hub, a fine-tune, a stack of LoRA adapters, an embedding model, a vector store, and a thick layer of open-source glue. LLM03 is the recognition that each of those borrowed pieces is a link in a supply chain — and that the traditional software supply chain now has a set of AI-specific failure modes bolted onto it.

Classic supply-chain risk hasn't gone away: the Python and JavaScript packages around a model are as exposed to typosquatting, dependency confusion, and abandoned maintainers as any other project. But LLM03 adds links that most software bills of materials have never had to describe — model weights, adapters, and datasets, distributed through hubs that were built for convenience and reach, not provenance.

The new links in the chain

publishpullPublic model hubweights, adapters,datasetsModel / LoRA adapteropaque, unsignedLoad on inference hosttorch.load / deserializeModel in productionPickle checkpointruns code on loadTyposquatted ortampered weights
How a borrowed model becomes code execution on your inference host.

The first is the pretrained model itself. When you download weights from a public repository, you are trusting whoever uploaded them and whoever could tamper with them in transit. A model is opaque: you cannot read its weights the way you read source, so a backdoor or a bias baked in during training is invisible to inspection. Typosquatted model names — a near-identical repo one character off from the popular one — exploit exactly that opacity.

The second is the serialization format. Older model files distributed as Python pickle objects (the classic PyTorch .bin) execute arbitrary code on load. Downloading and instantiating such a model is, mechanically, running a stranger's code on your inference host. This is why the ecosystem moved toward safetensors, a format that carries weights without executable payloads.

The third is fine-tunes and LoRA adapters. A low-rank adapter is a small, portable file that reshapes a base model's behaviour — and a poisoned adapter can install a trigger or degrade a safety property while the base model's own reputation vouches for it. The fourth is the training and fine-tuning data, where provenance and licence questions blur into the poisoning territory of LLM04.

The load itself is the exploit# a pickled checkpoint runs code the moment it is deserialized
model = torch.load("community-model-v2.bin") # arbitrary code executes here
Why it's LLM03: The AI supply chain inherits every weakness of the software supply chain and adds opaque artifacts — weights, adapters, datasets — that resist inspection. You are trusting components you fundamentally cannot read.

Defending the assembly line

  • Vet and pin your sources. Pull models and adapters from known publishers and pinned versions or commit hashes, never a mutable latest tag. Verify checksums and, where available, signatures before anything reaches an inference host.
  • Prefer non-executable formats. Use safetensors over pickle-based checkpoints, and load untrusted models in an isolated, network-restricted sandbox before you trust them anywhere near production.
  • Extend the SBOM to AI artifacts. Inventory not just packages but every model, adapter, dataset, and embedding model, with its origin and licence — an AI bill of materials you can actually audit.
  • Treat adapters as code. A third-party LoRA changes model behaviour; evaluate and red-team it against your safety and accuracy baselines before you merge it in.
  • Monitor for drift and disclosure. Track advisories for the models and libraries you depend on, and watch for behavioural drift that a swapped or tampered component would produce.

The hard part of LLM03 is that the artifacts most central to your system are the ones you can least inspect. You cannot diff a set of weights against a known-good version by reading it. That leaves provenance — knowing exactly where every component came from and proving it hasn't changed — as the primary control. And provenance starts with an inventory: you cannot vet a supply chain whose components you never catalogued.

Test for it — in practice
  • Pick one model or embedding your app loads and ask a blunt question: do you know its exact source, version and hash, or did someone just pip install the latest from a public hub? If you can't name the provenance, you can't trust it.
  • Open your dependency manifest and count how many packages the LLM glue code pulls in transitively. Anything you can't account for is untrusted code running next to your keys.

The full, at-scale version — tracing provenance and integrity across every model, dataset and dependency you ship — is what our assessment (and SecStudio agents) runs for you.

Keep reading
Data and Model Poisoning