Security researchers at Zafran Labs have detailed a set of three high-severity flaws in the Hugging Face Diffusers Python library that allow crafted model repositories to stealthily execute arbitrary code on the machines that load them. The vulnerabilities, collectively named “FaceHugger,” bypass the library’s trust_remote_code safeguard, turning a routine model download into an initial-access vector for data-science and MLOps environments.
Diffusers is a widely used Python library of pretrained diffusion models for generating video, images, and audio, and it was downloaded more than 8.1 million times in July 2026. Because the library is embedded in enterprise production pipelines, CI/CD systems, and container images, the researchers said the flaws convert a trusted model load into code execution, with the repository itself carrying the payload.
The Three FaceHugger Flaws Share a TOCTOU Root Cause
The root cause behind all three vulnerabilities is a Time-of-Check to Time-of-Use (TOCTOU) pattern. Diffusers’ trust check lives entirely in the first phase of a two-request download; any method that makes the loader see custom code that the gate did not examine bypasses the safeguard. The researchers found three distinct ways to reach that outcome.
CVE-2026-44827 and CVE-2026-44513: Injection Through the custom_pipeline Flow
Two of the flaws, CVE-2026-44827 and CVE-2026-44513, both rated CVSS 8.8, achieve code injection through the custom_pipeline flow even when trust_remote_code is set to False. In one case, a crafted pipeline named “None.py” is enough to slip executable code past the gate. In the other, the same custom_pipeline path is abused without the trust flag being enabled at all.
CVE-2026-45804: The Race Between Two Download Calls
The third flaw, CVE-2026-45804 at CVSS 7.5, is a race condition. An attacker can modify the configuration between the hf_hub_download and snapshot_download HTTP calls that the loader performs, so the configuration used at load time differs from the configuration that the trust gate validated. The gap between the two requests is the window the attacker exploits.
Why Diffusers’ Reach Extends Into Production Pipelines
The practical risk stems from how the library is used rather than from the library alone. Diffusers models are loaded inside data-science notebooks, batch inference jobs, and container images that move through CI/CD systems. An attacker who controls a model repository can therefore reach environments that often hold training data, credentials, and deployment infrastructure. Zafran Labs noted that artifacts pulled from AI repositories are frequently treated as passive data, even though configuration files, loaders, and custom pipeline code can cross into executable code and turn a routine model load into an initial-access vector.
Patching to 0.38.0 and Auditing Custom Pipelines
The fixes landed in Diffusers version 0.38.0, which was released in early May. Any user invoking from_pretrained with custom pipelines is impacted and should update. For environments that cannot upgrade immediately, the researchers recommend calling from_pretrained only with fully trusted, audited sources, not pointing custom_pipeline at a Hub repository different from the primary model, and inspecting local snapshots for unexpected .py files before loading.
The FaceHugger disclosure arrives as model registries consolidate into central distribution points for code as much as weights. Hugging Face’s position as the hub of the AI ecosystem, often described as the GitHub of the AI era, makes its repository gates a systemic control surface, in the same way package registries became a systemic control surface for software supply chains after earlier dependency-supply-chain incidents. The researchers’ point that model artifacts are frequently treated as passive data cuts to the heart of that risk: a configuration file is not inert, and a loader that reads it is running a program. Until repository platforms apply execution-time isolation to custom pipeline code, teams that load third-party models will need to treat every pull as a code review decision, not a data download, and to keep the environments that load those models outside the blast radius of a single compromised repository.
