LLM-Squatting Attack [2026]: Malicious Model Risk
Bottom Line
Registry trust is not artifact trust. If your pipeline resolves a model by name and then loads unsafe weights or remote code, a squatted model can turn a familiar pull into arbitrary code execution.
Key Takeaways
- ›No CVE is assigned here; this is a supply-chain attack pattern, not a single library bug.
- ›JFrog reported around 100 malicious Hugging Face models in its February 27, 2024 disclosure.
- ›Hugging Face scans every commit, but scanning does not replace revision pinning or format restrictions.
- ›Internetware 2025 found 1,574 potentially malicious squatting models and 625 squatting datasets.
- ›Best defense: pin commit hashes, prefer safetensors, and block trustremotecode by default.
The next AI supply-chain problem does not need a kernel exploit or a dependency confusion chain. It can start with something much simpler: an attacker publishing a model that looks close enough to a trusted one, then waiting for a pipeline to pull it by name and deserialize it unsafely. That pattern, which this piece calls LLM-Squatting, sits at the intersection of registry naming, model serialization, and automation. The dangerous part is not just a typo. It is the combination of human trust, mutable model repos, and code-capable model formats.
- No CVE: this is an attack class and operational weakness, not one discrete bug.
- Observed in the wild: JFrog disclosed a malicious Hugging Face model with a silent backdoor on February 27, 2024.
- At scale: Hugging Face docs now describe a hub with over 2M models, which makes namespace trust a security problem, not just an ergonomics issue.
- Academic signal: the Internetware 2025 study reported 1,574 potentially malicious squatting models.
- Defensive priority: pin by revision, prefer safetensors, and treat trustremotecode as an exception path.
CVE Summary Card
Bottom Line
A public model registry name is only a locator, not a security boundary. The moment your loader accepts mutable revisions, unsafe serialization, or remote repository code, a squatted model can become an execution primitive.
| Field | Value |
|---|---|
| Incident type | AI supply-chain attack pattern using registry squatting and unsafe model loading |
| CVE status | None assigned as of May 10, 2026 |
| Primary ecosystems | Public model registries, especially workflows built around Hugging Face-style model repositories |
| Execution path | Deserializing unsafe model files or enabling trustremotecode on untrusted repos |
| Impact | Arbitrary code execution, credential exposure, poisoned outputs, persistence, data exfiltration |
| Key public evidence | JFrog's February 27, 2024 disclosure, Hugging Face's security docs, and the Internetware 2025 study |
The naming matters because teams still think in package-manager terms: if the repo name looks familiar and the model loads successfully, the artifact feels legitimate. But model hubs are not only distribution channels. They are execution-adjacent artifact stores. Hugging Face explicitly warns that some formats are vulnerable to arbitrary code execution and documents both pickle scanning and the safer safetensors format. That is the core shift: in AI, a model file can behave more like a binary than a passive asset.
Vulnerable Code Anatomy
What the insecure path looks like
Most real-world exposure comes from three design choices landing in the same code path:
- The application resolves a model by a human-readable identifier instead of an immutable digest or commit hash.
- The loader accepts formats with executable deserialization behavior, especially pickle-backed weights.
- The runtime enables custom repository code through trustremotecode or equivalent hooks.
import os
from transformers import AutoModelForCausalLM
model_id = os.environ['MODEL_ID']
model = AutoModelForCausalLM.from_pretrained(
model_id,
trust_remote_code=True
)This snippet is short, common, and dangerous. The model identifier is mutable, the revision is unspecified, and remote code is explicitly trusted. Hugging Face's own Transformers loading guide says custom models loaded with trustremotecode=True should be pinned to a specific revision for extra security. If that warning exists in vendor docs, defenders should read it as a sign that the threat is operationally real.
Why model registries are different from package registries
- A model repo can hold weights, config, tokenizer files, and executable support code in one namespace.
- Loaders often fetch the latest state by default, which creates hidden drift.
- Model provenance is harder to inspect than source packages because the payload may live in serialized weights, not just plain text.
- Operational teams may over-trust popularity signals such as likes, downloads, or organization-looking names.
That last point is where squatting becomes effective. The attacker does not need to defeat your sandbox if your pipeline imports the wrong model and runs its load-time behavior itself.
Attack Timeline
- February 27, 2024: JFrog published Data Scientists Targeted by Malicious Hugging Face ML Models with Silent Backdoor, describing a malicious model whose load path executed code and opened a backdoor. JFrog said its analysis had identified around 100 malicious models to date.
- March 4, 2025: JFrog announced broader scanning integration with Hugging Face and reported that its technology reduced false positives by 96%, while also noting that over 28k models on the hub were marked suspicious by simpler methods.
- October 2025: the Internetware 2025 study on typosquatting in the Hugging Face ecosystem reported 1,574 potentially malicious squatting models, 625 squatting datasets, and 302 squatting organizations.
- May 10, 2026: Hugging Face documentation describes layered protections including malware scanning on every commit, pickle scanning, and third-party scanner integrations from JFrog and Protect AI.
The timeline matters because it shows a pattern, not a one-off curiosity. First came proof that malicious models could execute code during load. Then came ecosystem-scale evidence that naming abuse exists across models, datasets, and organizations. Finally, platform operators expanded scanning because the problem was persistent enough to justify productized controls.
Exploitation Walkthrough
Conceptual attacker path
- The attacker picks a high-trust target name, then creates a lookalike, mirror-style, or typo-derived repository.
- The repo includes either unsafe serialized weights, executable custom code, or both.
- The attacker adds plausible metadata: benchmark claims, quantization labels, familiar README structure, and borrowed examples.
- A victim pipeline resolves the model by name, branch, or latest revision instead of an immutable reference.
- The loader deserializes the artifact or executes repo-provided code, giving the attacker a foothold.
- The payload steals tokens, writes persistence, modifies inference behavior, or exfiltrates environment data.
Where defenders usually misread the risk
- They assume scanner badges equal safety, even though scanners are probabilistic and can miss novel payloads.
- They assume a familiar org or repo name is enough provenance.
- They test only output quality, not load-time side effects.
- They separate 'model risk' from 'code risk', even though the attack crosses both.
That separation is the big mistake. In software supply chain terms, LLM-Squatting is not just an integrity failure at discovery time. It is an execution-control failure during artifact consumption.
Hardening Guide
1. Make resolution immutable
Hugging Face's download APIs support a revision parameter that can be a branch, tag, or commit hash. Use the commit hash.
from huggingface_hub import snapshot_download
local_path = snapshot_download(
repo_id='org/model-name',
revision='<commit-hash>',
allow_patterns=['*.json', '*.safetensors', 'tokenizer.*']
)- Pin to a commit hash, not main.
- Store the approved revision in IaC or deployment metadata.
- Require change review before updating the pinned revision.
2. Prefer safer formats
Hugging Face documents that from_pretrained() loads safetensors when available and notes that traditional pickle serialization is known to be insecure. That should become a policy, not a preference.
- Allow safetensors by default.
- Block pickle-backed formats unless there is a documented exception.
- Record which services still depend on unsafe deserialization and burn that list down over time.
3. Treat trustremotecode as a security exception
- Disable it by default in shared libraries and platform templates.
- If you must enable it, pin the exact revision and run the load in an isolated environment.
- Review repository code the same way you review a third-party library.
4. Add runtime containment
- Load new models in short-lived sandboxes.
- Strip cloud credentials and unnecessary secrets from the execution environment.
- Apply egress controls so a compromised loader cannot beacon freely.
- Log file hashes, commit hashes, and network attempts during model initialization.
5. Clean your incident exhaust
When you share traces, prompts, env dumps, or notebook output with vendors and responders, scrub them first. A simple operational habit is to run sensitive logs through TechBytes' Data Masking Tool before posting them into tickets or chats.
Architectural Lessons
Model identity must beat model naming
Package security learned this lesson years ago: names are for humans, digests are for systems. Public model registries need the same discipline. A model repo name should help discovery, but the deployment system should trust only immutable identity plus approved provenance.
Scanning is necessary but not sufficient
Hugging Face now documents malware scanning on every commit and multiple security scanners. That is valuable, but it is still a detection layer. Good architecture assumes some malicious artifacts will be missed, some safe artifacts will be misflagged, and some organizations will over-trust green badges. Build controls around that reality.
- Discovery controls: allowlists for organizations, naming policies, and mirror approval workflows.
- Integrity controls: commit pinning, signatures where available, and internal artifact attestation.
- Execution controls: sandboxed loading, no-default remote code, and egress restrictions.
- Response controls: rapid revocation, cache invalidation, and reproducible rollback to last-known-good revisions.
The AI stack collapses old boundaries
In classic app architecture, teams often separate binaries, configs, and data. Model repos blur those boundaries on purpose because AI ergonomics reward one-command loading. That convenience is useful, but it also means your model pipeline now owns code-trust problems whether or not the team calls itself a security team.
The architectural lesson is blunt: treat externally sourced models as executable third-party artifacts. If a public registry name can influence what bytes your workload deserializes or what code your runtime imports, you are already in software supply-chain territory. LLM-Squatting is just the most visible name for that reality.
Frequently Asked Questions
What is LLM-Squatting in a model registry? +
Can a Hugging Face model execute code just by being loaded? +
trust_remote_code=True.Is this a CVE or a misconfiguration? +
Does malware scanning on the registry solve the problem? +
Get Engineering Deep-Dives in Your Inbox
Weekly breakdowns of architecture, security, and developer tooling — no fluff.