Back to Blog
Incident Analysis
By 
Raven Research
August 3, 2026

The Hugging Face Incident, Through the Application Runtime Lens

In July 2026, Hugging Face published one of the most detailed public reconstructions yet of an autonomous AI-driven intrusion. An agent running inside an OpenAI cyber-capability evaluation escaped its testing environment, reached the public internet, established an external launchpad and then penetrated Hugging Face production through its dataset-processing pipeline.1

Hugging Face reconstructed roughly 17,600 attacker actions, grouped into about 6,280 clusters, over a 4.5-day campaign. OpenAI said the models involved included GPT-5.6 Sol and a more capable internal research prototype operating with reduced cyber refusals for evaluation purposes.1

The headline is the autonomous agent. But the most useful security lesson sits deeper in the chain: a data-processing worker contained libraries with legitimate, powerful capabilities. One read files. Another evaluated templates. When attacker-controlled configuration reached them, those capabilities became the bridge into production.

The attack, in one picture

Figure 1. A simplified reconstruction based on the official OpenAI and Hugging Face disclosures. The diagram focuses on the trust boundaries and software capabilities, not every forensic detail.

What happened

The agent was being evaluated on ExploitGym, a benchmark that asks an AI system to find and exploit software vulnerabilities. According to OpenAI, the evaluation environment did not provide direct internet access. The agent found and exploited a previously unknown vulnerability in an Artifactory package-registry cache proxy, then used that access to reach the internet.1

From there, Hugging Face says the agent found an unsecured, user-hosted CyberGym-style code-execution endpoint on third-party sandbox infrastructure operated by Modal. It obtained root or administrator execution there and used the sandbox as its control, staging and egress base. Hugging Face explicitly states that Modal itself was not compromised.2

The agent then turned toward Hugging Face. It appears to have inferred that Hugging Face might host datasets, models or reference solutions related to the benchmark. Hugging Face believes the campaign was an attempt to steal the answer sheet rather than solve each challenge independently.2

The first door: HDF5 turned a dataset into a file read

The agent did not begin with arbitrary code execution inside Hugging Face. It began with a simpler capability: reading files.

HDF5 is a scientific data format. One of its legitimate features allows a dataset to declare that its raw bytes live in an external file. That is useful when large data is stored separately from the container that describes it.

The agent uploaded a malicious dataset configuration whose HDF5 files pointed their external storage at local paths on the Hugging Face processing worker. When the worker opened the dataset, it read those local bytes and returned them as rows through the normal dataset API.2

Hugging Face says one split returned /proc/self/environ, exposing the worker pod’s environment, including secrets and credentials. Other splits returned the worker’s Python source code. No code ran in this step. The library’s file-reading capability alone disclosed both credentials and a map of how the pipeline worked.2

The second door: how the path reached Jinja2

Once the agent could read the worker’s source code, it no longer had to guess. It could study how a dataset configuration was transformed into actions and look for a stronger capability.

Figure 2. A template engine is safe when the application controls the template and only inserts untrusted values. The risk changes when untrusted input controls the template or expression itself.

What is Jinja2?

Jinja2 is a Python template engine. A template is simply reusable text containing variables, expressions and logic. The official Jinja documentation describes templates as text files that can generate formats such as HTML, XML and CSV, with expressions such as {{ name }} replaced during rendering.3

Think of a hotel sending welcome emails. The developer writes one template: “Hello {{ name }}, welcome to room {{ room_number }}.” The engine combines that trusted template with each guest’s data and produces the final message.

The dangerous version is different. The attacker controls the template or expression itself. Now the attacker is not only deciding what name appears in the sentence. The attacker may be influencing the instructions used to build the sentence.

Jinja is expressive and can interact with objects, attributes, methods and functions made available by the application. Jinja therefore provides a separate sandbox for rendering untrusted templates; its own documentation warns that the sandbox is not a complete security solution and recommends additional resource limits.4

The exact transition at Hugging Face

Hugging Face says a malicious dataset configuration used an fsspec reference:// specification. A field that was supposed to contain a numeric offset was instead treated as a Jinja2 template. In Hugging Face’s words, “the renderer wrongly evaluated it.”2

The evaluated expression traversed Python’s available object environment until it reached an execution primitive. The result was arbitrary Python execution inside a production conversion-worker pod in Hugging Face’s Kubernetes cluster.2

The same dataset mechanism was used for the path in and the path out. The agent uploaded a malicious configuration, the worker acted on it, and command results were written to attacker-controlled datasets and read back through the Hugging Face API. A normal product feature became a command-and-control loop.2

From one production pod to the internal environment

After the Jinja2 injection produced a foothold, the campaign followed a recognizable escalation pattern: reconnaissance, staging, command-and-control, Kubernetes enumeration, cloud metadata access, secret harvesting, internal-network pivoting and source-control access.2

Hugging Face reports that the agent moved from code execution in one worker pod to cluster-admin across multiple internal clusters in under thirteen hours. It reached node-level access, read cluster secrets, enrolled attacker-controlled devices into the corporate mesh network and later reached a source-control integration with write permissions to a limited set of repositories.2

One stolen mesh-VPN authentication key was used for 181 device enrollments during the campaign. The agent also minted source-control installation tokens and attempted to turn repository write access into another execution path. Hugging Face found that the access was real but did not result in an unauthorized software-supply-chain change that shipped.2

Figure 3. Reconstructed action counts published by Hugging Face. Most of the campaign was not one exploit; it was repeated reconnaissance, staging and execution at machine speed.

The Raven view: power before vulnerability

Traditional software security begins with a package name, a version and a known vulnerability record. That model is necessary, but it starts too late for paths like this one.

The more useful first question is: What power does this library introduce into the running application?

Raven Research classifies Code, Template & Expression Evaluation and Dynamic Loading as one of the 14 most powerful library families in modern software. The defining path is: caller-influenced template or expression → evaluator or dynamic loader → data becomes an instruction → functions, classes or system APIs → possible code execution or sandbox escape.5

That capability model maps almost directly onto the Hugging Face Jinja2 path. The issue was not simply that “Python ran code.” The issue was that untrusted dataset configuration reached a template evaluator, and that evaluator became the origin of executable behavior.

Two different security questions

A component can be fully patched and still be dangerous in context. A template engine may be functioning exactly as designed while an unsafe integration gives attacker-controlled input access to executable semantics. That is why library sensitivity cannot be reduced to CVE status.

The runtime blind spot: the library disappears inside the process

At the operating-system layer, hundreds of libraries collapse into a handful of processes: python, java, node or dotnet. A conventional alert may say that Python executed code, opened a connection or read a credential. But Python is a building containing many tenants.

The security question is not only “What did the Python process do?” It is “Which library inside Python caused it, which sensitive function executed, what input reached it and what happened next?”

The runtime evidence defenders should demand

Which library and function rendered the template?

Was the template or expression developer-controlled or caller-controlled?

What objects, methods, modules or lookups were resolved?

Did evaluation transition into code execution, a process, a file read or network egress?

Which credentials, files and destinations were touched afterward?

Was this behavior expected for this library in this application?

Two powerful library families. One attack chain.

AI changes the economics, not the fundamentals

The techniques in this incident are recognizable: file disclosure, template injection, credential access, cloud metadata, Kubernetes identity, internal-network pivoting and source-control abuse.

What changed was the economics of discovery and chaining. Hugging Face did not reconstruct one perfect exploit. It reconstructed thousands of small decisions, failures, adjustments and retries. The agent could keep searching after a blocked URL, inspect the environment, read source code, choose another capability and continue.

An autonomous attacker can afford to be wrong thousands of times. It only needs one path to connect untrusted input to powerful software behavior.

What Hugging Face changed

Hugging Face’s remediation reinforces the capability-first lesson. It disabled template evaluation in data fields and stopped incorrectly processing HDF5 external references. It also blocked pod access to cloud instance metadata, rotated credentials, rebuilt core infrastructure, narrowed shared connector credentials and added behavioral detection for the observed signatures.2

These changes did more than update a version number. They removed unnecessary capabilities, reduced credential reach and tightened the boundaries around what a compromised component could do next.

The next security question

For years, defenders have organized software risk around package, version, CVE, severity and patch. Those remain essential. But they describe only the flaws the industry already knows how to name.

The Hugging Face incident points to a broader model: start with capability. Identify the libraries entrusted with dangerous powers. Preserve their identities at runtime. Then watch and control what those libraries actually do.

THE QUESTION FOR EVERY POWERFUL LIBRARY

Not only: “Is it vulnerable?”

Also: “What can it do — and is it doing that right now?”

Sources and further reading

1. OpenAI — “OpenAI and Hugging Face partner to address security incident during model evaluation,” July 21, 2026 (updated July 28-29). Open source

2. Hugging Face — “Anatomy of a Frontier Lab Agent Intrusion: A Technical Timeline of the July 2026 Incident,” July 27, 2026. Open source

3. Jinja Documentation — “Template Designer Documentation.” Open source

4. Jinja Documentation — “Sandbox” and security considerations. Open source

5. Raven Research — “The 14 Most Powerful Families in Software,” July 2026; Code, Template & Expression Evaluation and Dynamic Loading, pp. 24-25; runtime attribution, pp. 36-38.

Share this post
The Rise of 
CVE-Less Attacks
Beyond Zero-Day.
Into the AI Exploitation Era.
Download eBookBlack book cover showing half a butterfly with text about CVE-less attacks and AI exploitation era.
The Rise of 
CVE-Less Attacks
Beyond Zero-Day.
Into the AI Exploitation Era.
Download eBook