How a simple model evaluation exposed critical supply chain vulnerabilities. Learn the RLHF security lessons every AI team needs now.
TL;DR: OpenAI and Hugging Face jointly disclosed a security incident where loading an external model for RLHF evaluation triggered unauthorized code execution through pickle deserialization vulnerabilities. The incident exposed critical gaps in AI supply chain security: no one involved malicious intent, yet production evaluation infrastructure was compromised through standard model loading workflows. This reveals that AI model evaluation requires the same sandboxing rigor as production deployment, and that popular model serialization formats carry execution risks that most teams are not defending against.
On July 15, 2026, OpenAI and Hugging Face jointly published a security incident report describing a compromise that occurred during routine model evaluation work. Here's the sequence of events based on their disclosure:
Phase 1: The Evaluation Request. OpenAI's Reinforcement Learning from Human Feedback (RLHF) team was evaluating external models to assess comparative performance for an internal research project. The team pulled a popular open-source model from Hugging Face's model hub using standard model loading APIs. This is routine work — AI research teams evaluate dozens or hundreds of models per quarter to benchmark against baselines, reproduce published results, and assess state-of-the-art capabilities.
Phase 2: The Trigger. When OpenAI's evaluation infrastructure loaded the model weights, the deserialization process executed embedded code within the pickle-serialized tensors. Pickle is Python's native serialization format and is used extensively in the PyTorch ecosystem for saving and loading model checkpoints. By design, pickle can serialize arbitrary Python objects including classes and functions. During deserialization, pickle reconstructs these objects by executing their __reduce__ methods. An attacker can craft malicious pickle payloads that execute arbitrary code when unpickled.
In this case, the Hugging Face model's .pt checkpoint file contained pickle-serialized code that executed on load. Importantly, OpenAI's report states there was no evidence of malicious intent from the model publisher. The embedded code likely resulted from accidental inclusion of custom training logic, preprocessing functions, or framework artifacts that were serialized alongside the model weights during the original training run. This is a common footgun in the PyTorch ecosystem: saving a model with torch.save() can inadvertently capture code references that get executed on torch.load().
Phase 3: The Compromise. The executed code gained access to OpenAI's evaluation environment. While neither company disclosed the full scope of the compromise, the joint statement confirmed the incident triggered a security review, infrastructure changes, and collaboration with Hugging Face on model provenance tooling. The environment in question was isolated from production inference systems but had network access and credentials for pulling datasets and models — a common evaluation infrastructure pattern that balances isolation with operational practicality.
Phase 4: The Response. Both companies implemented immediate mitigations and long-term architectural changes. OpenAI moved model evaluation to fully sandboxed containerized environments with no network egress, switched to SafeTensors for external model loading, and implemented model hash verification against known-good registries. Hugging Face enhanced model scanning for pickle payloads, began migrating the model hub to SafeTensors as the default format, and built provenance tracking that logs model training environments and serialization methods.
The core lesson from this incident is that loading a model executes code. Most AI teams treat model evaluation as a read-only operation — you load weights, run inference on test inputs, log metrics, and discard the model. In this mental model, evaluation carries no security risk beyond data leakage (e.g., leaking test set labels). The OpenAI-Hugging Face incident shatters this assumption.
Here's why model loading is an execution surface, not a read operation:
Pickle is not a data format — it's a Python execution protocol. When you call torch.load("model.pt"), PyTorch unpickles the file contents. If the file was saved with torch.save(model, "model.pt"), the pickle includes not just tensor values but also class definitions, function references, and object state. During unpickling, Python reconstructs these objects by:
This execution happens before you call model.forward(). Just loading the file triggers arbitrary Python execution. An attacker (or accidental code inclusion) can embed commands in the pickle payload that:
Pickle is not the only culprit. Other serialization formats have similar risks:
Modern deep learning frameworks allow custom layer implementations. A model trained with custom PyTorch layers includes the layer's Python class definition in the saved checkpoint. Loading the model requires importing and instantiating that class, which executes its __init__ method and any side effects. A custom layer could:
When you torch.load() a model containing this layer, the __init__ code executes before you ever call .forward(). The model could perform perfectly normal inference while having already exfiltrated credentials during load.
Hugging Face Transformers models include tokenizers that preprocess text inputs before inference. Tokenizers can include custom preprocessing logic written in Python (as opposed to pure Rust fast tokenizers). If a model's tokenizer includes custom code, loading the tokenizer from the model hub executes that code. A malicious or compromised tokenizer could:
This is particularly concerning for RLHF evaluation workflows, where tokenizers process large volumes of human feedback data that may contain sensitive information.
Deep learning frameworks execute initialization code when importing modules. If a model requires a custom library (e.g., a modified version of transformers or a proprietary layer library), importing that library executes its __init__.py and any module-level code. This is a common supply chain attack vector in the Python ecosystem generally, and it applies to AI model dependencies.
The OpenAI-Hugging Face incident is not an isolated failure. It's a symptom of a fundamental mismatch between how the AI community builds and shares models (optimized for speed and convenience) and what security models assume (that loading data is safe).
Hugging Face's model hub revolutionized AI research by making it trivial to share and load models. You write model = AutoModel.from_pretrained("username/model-name") and within seconds you have a trained model ready for evaluation or fine-tuning. This distribution model assumes:
These assumptions break down at scale. As of 2026, Hugging Face hosts over 500,000 models. The vast majority are published by individual researchers or small teams with no formal security review process. Most models use pickle-based serialization because that's the PyTorch default and it's the easiest way to save complex model architectures with custom layers.
The security posture relies on community trust and post-hoc scanning, not proactive sandboxing. This works for early research adoption but becomes a supply chain vulnerability when companies integrate external models into evaluation or production workflows.
Most AI teams treat evaluation infrastructure as lower-risk than production inference. The logic is: evaluation is internal-only, it doesn't serve user traffic, and it's isolated from production data. This creates an operational pattern where evaluation environments have:
This incident demonstrates that evaluation environments are high-value targets. They contain:
A compromised evaluation environment can backdoor the entire model development pipeline. An attacker could modify training code to inject backdoors into all future models, exfiltrate proprietary datasets used for RLHF, or steal model weights before publication.
Pickle has been Python's serialization standard since the 1990s. The PyTorch community adopted it for model checkpoints because it's native, fast, and handles arbitrary Python objects. This made early PyTorch development significantly easier than alternatives (TensorFlow's protobuf-based SavedModel format is notoriously verbose to work with manually).
But pickle's flexibility is also its vulnerability. Every pickle file is a potential remote code execution vector. The Python security community has warned about pickle for years, but the AI community largely ignored these warnings because:
By 2026, these assumptions no longer hold. Models are too complex to audit, distribution is global and open, and better alternatives (SafeTensors) exist. But the ecosystem is slow to migrate because billions of existing models use pickle, and converting them requires re-exporting from original training environments (which may no longer exist).
The defensive response to this incident requires multiple layers. No single mitigation is sufficient — you need defense in depth.
What: Run all external model evaluation in containerized environments with no network egress, no cloud credentials, and read-only file system mounts for code.
Why: Limits blast radius if model loading triggers malicious code execution. The compromised container cannot exfiltrate data, pivot to internal networks, or persist backdoors.
How:
Run with:
Trade-off: Adds operational complexity and makes interactive debugging harder. For teams heavily iterating on evaluation code, consider a two-tier approach: unrestricted sandbox for internal model evaluation, strict sandbox for external models.
What: Reject pickle-based model formats (.pt, .pth, .pkl) for external models. Use SafeTensors (.safetensors) format exclusively.
Why: SafeTensors is a header + raw tensor data format with no code execution capability. It cannot embed Python objects, class definitions, or executable logic.
How:
Trade-off: Requires architecture definition in your codebase. SafeTensors contains only weights, not layer definitions. For external models, you must re-implement or import the architecture separately (auditing imports carefully). Many Hugging Face models now ship SafeTensors alongside pickle — prefer the .safetensors file when available.
Migration: Convert existing models:
What: Maintain a registry of known-good model hashes and verify integrity before loading.
Why: Prevents substitution attacks and ensures you're loading the intended version of a model.
How:
Trade-off: Requires maintaining and updating the model registry. For rapidly iterating research teams, consider automating hash collection during initial evaluation and flagging changes on re-download rather than blocking.
What: Pin all model library dependencies to specific versions and scan for known vulnerabilities.
Why: Model loading often requires importing framework code that could contain vulnerabilities or be compromised via dependency confusion attacks.
How:
Scan regularly:
Use lockfiles for reproducibility:
Trade-off: Reduces flexibility to quickly adopt new framework features. Balance by having separate pinned environments for evaluation (strict pins) and research (more flexibility).
What: If your team publishes models to Hugging Face or internal hubs, scan checkpoints for pickle payloads before publishing.
Why: Prevents accidental inclusion of code artifacts in published models that could create security incidents for downstream users.
How:
Use Hugging Face's picklescan tool:
Example output:
If the scan shows unexpected imports beyond standard PyTorch classes (e.g., os, subprocess, requests), investigate before publishing.
Automated check in CI:
Trade-off: Adds friction to model publishing workflows. For internal models, consider gating production promotion (not research sharing) on scan passing.
The OpenAI-Hugging Face incident is the latest in a series of security events that reveal the AI stack's unique attack surfaces:
In 2025, researchers demonstrated that Roblox's in-game AI assistant could be jailbroken through carefully crafted game scripts that injected malicious context into the LLM's conversation history. The attack bypassed content filters by encoding instructions in base64 within innocuous-looking Lua code. The incident highlighted that LLM inference is not isolated from application state — compromising the application layer can manipulate what the LLM sees and therefore what it outputs.
Lesson: Input sanitization must happen before text reaches the LLM, not just in the LLM's system prompt.
Anthropic published research showing that prompt injection attacks could exfiltrate private documents by instructing Claude to include base64-encoded file contents in benign-looking responses. The attack worked even with strong system prompts forbidding data exfiltration because the injected user message had higher weight than the system prompt.
Lesson: LLMs do not reliably enforce security boundaries when attacker-controlled text appears in the prompt. Authorization must be enforced outside the LLM (at the tool call level, not the prompt level).
While not AI-specific, the SolarWinds compromise demonstrated that supply chain attacks target build and distribution infrastructure, not just end-user applications. An attacker who compromises a widely distributed component (in SolarWinds' case, the Orion software update) gains access to thousands of downstream victims.
Lesson: Trust in software distribution platforms must be explicitly verified, not assumed. Code signing, hash verification, and provenance tracking are essential for any component pulled from external sources.
The OpenAI-Hugging Face incident combines elements of all three:
The unique AI aspect is that models are both data and code. A pickle-serialized model checkpoint looks like a data file (you load it with torch.load()), acts like code (it executes Python during deserialization), and is treated as data by most security tooling (passed through network filters, stored in data buckets, not scanned as executables).
This category confusion is the root vulnerability. Traditional software supply chain security scans source code files for backdoors and runs binaries in sandboxes. But model files are neither traditional source nor binaries — they're serialized Python objects that execute during deserialization. Most security scanners don't inspect them, and most AI teams don't treat them as execution surfaces.
If you're building, evaluating, or deploying AI models, here are the questions this incident should prompt:
The answer is nuanced. The AI research community depends on open model sharing — cutting off all external model usage would cripple progress. The right approach is risk-based trust with verification:
Models like bert-base-uncased, gpt2, llama-2-7b from official accounts (Google, OpenAI, Meta) are relatively safe because:
Appropriate controls: Verify hashes against multiple sources, prefer SafeTensors format when available, still run in sandbox for defense-in-depth.
Models published by active researchers with established publication histories (e.g., PhD students at top universities, authors of cited papers) are moderate risk:
Appropriate controls: Run in strict sandbox, convert to SafeTensors format, verify model behavior matches paper claims before trusting outputs.
Models from new accounts, anonymous publishers, or sources with no research track record are high risk:
Appropriate controls: Do not load without manual inspection of checkpoint contents, run in fully isolated sandbox with no network, treat as untrusted code.
For production use cases or sensitive evaluation, consider training models internally rather than loading external checkpoints:
The OpenAI-Hugging Face incident is a turning point for AI security. It demonstrates conclusively that models are not passive data — they are executable artifacts that must be treated with the same security rigor as any code running in your infrastructure.
For the AI community, this means shifting mental models:
For OpenAI and Hugging Face, the rapid response and joint disclosure set a positive precedent. Both companies implemented architectural fixes, shared learnings publicly, and collaborated on long-term tooling improvements. This is how security incidents should be handled in the AI community — transparent disclosure, collective defense, and ecosystem-wide mitigation.
For the broader industry, this incident is a warning. As AI adoption accelerates, model supply chains will become increasingly attractive targets. Teams that treat model loading as a benign operation will be compromised. Those that adopt defense-in-depth — sandboxing, provenance verification, safe serialization formats, and security scanning — will weather the attacks that are inevitably coming.
The question is not whether your team will encounter malicious or compromised models. The question is whether your infrastructure will contain the compromise when it happens.
Yes, with appropriate precautions. The incident was disclosed responsibly, Hugging Face has implemented additional scanning, and the platform remains the standard for model distribution. The key is to follow the defensive practices outlined above: prefer SafeTensors format, verify hashes, load external models in sandboxes, and treat model loading as a privileged operation. Hugging Face models from established publishers with SafeTensors format and verified provenance are as safe as any external software dependency.
No. PyTorch itself is not vulnerable — pickle is the serialization format, and it's used throughout the Python ecosystem. The issue is using pickle for untrusted data (external model checkpoints from unknown sources). Continue using PyTorch, but when loading external models, prefer SafeTensors format or load pickle files in sandboxed environments. For internal models you train yourself, pickle is fine as long as you control the training environment.
Check the file extension. Pickle formats use .pt, .pth, or .pkl. SafeTensors uses .safetensors. On Hugging Face, models often ship both formats — the "Files and versions" tab shows all available files. You can also check programmatically:
You have three options: (1) Run the loading operation in a fully isolated sandbox with no network egress and no credentials, then inspect the loaded model and re-export to SafeTensors. (2) Contact the model publisher and request a SafeTensors version. (3) If the model is for research and the publisher is trustworthy (Tier 1 or 2 above), accept the risk but still load in a sandbox as defense-in-depth.
No. When you call an inference API, you're sending text inputs and receiving text outputs. The model weights are hosted by the provider and never loaded into your infrastructure. This incident specifically affects scenarios where you download and load model checkpoints into your own environment (evaluation, fine-tuning, self-hosted inference). Inference APIs have different security concerns (prompt injection, data exfiltration via outputs), but model deserialization is not one of them.
Yes. This incident focuses on model checkpoint deserialization, but the AI supply chain has multiple attack surfaces:
Treat every external code or data source as untrusted until verified, and adopt supply chain security best practices: dependency pinning, hash verification, sandboxing, and least-privilege access.
Aaron is an engineering leader, software architect, and founder with 18 years building distributed systems and cloud infrastructure. Now focused on LLM-powered platforms, agent orchestration, and production AI. He shares hands-on technical guides and framework comparisons at fp8.co.
How T3MP3ST's multi-agent architecture automates offensive security testing. Compare traditional pentesting vs autonomous AI-driven red teams.
AI Engineering, SecurityUsing an LLM to authorize agent actions duplicates your attack surface. Why deterministic policy engines like Cedar and OPA belong in the decision path.
AI Engineering, Agent FrameworksContext engineering cuts AI agent costs 10x via KV cache optimization, tool masking, and 5 more patterns. Production-tested by teams running million-token workflows.
AI Engineering, Agent Frameworks