Products Lemma APIProof issuance & verification platformTrust402Delegate to agents, and transactSealSign-in for the agent era — no keys handed over
Use cases Manufacturing & Critical InfraInspection Record AssuranceFinance & FinTechCounterparty Record VerificationPublic SectorCertificate-less ProceduresHealthcareQualified Worker AssuranceProcurement & Supply ChainSupplier Credential MonitoringMedia & ContentContent AuthenticityService & RetailCross-group IdentityAI Adoption (cross-industry)AI Run GovernanceDevelopers & Agent OpsAgent Authority Control ▸ Browse the use-case index
Pricing
Resources Critical BriefThe frontier of AI × trustBlogThinking and implementation notesDocumentationAPI & specsVerification CenterReal verification & issuance countsAbout usFRAME00, Inc.ContactSales & press inquiriesGlossaryDefinitionsFAQFrequently asked questions
Dashboard ↗ JA
Home / Critical Brief / No. 121
No. 121 Critical Brief · Verifiable AI

Hugging Face Diffusers "FaceHugger": loading a model was enough to run arbitrary code (Zafran research, CVE-2026-44827 et al.)

3CVEs
Flaws tracked as CVEs, scored CVSS 8.8, 7.5 and 8.8 (by GitHub as CNA)
~7M
Monthly Diffusers downloads, running inside production AI pipelines and CI/CD
03-19→05-01
From Zafran's report of the first two flaws to the release of the fixed Diffusers 0.38.0
CountryGlobal
Incident date2026-07-27
Published2026-08-04
AuthorsLemma Critical Team
Contents
  1. 01Summary
  2. 02What got through
  3. 03Pre-execution check
  4. 04What Lemma does
  5. 05Facts and timeline
  6. 06Sources

Summary

Merely loading a malicious model repository ran arbitrary Python on the user’s machine. The trust_remote_code safeguard, built to stop unreviewed code, refused custom code by default. But a model download is split into two non-atomic HTTP requests, a config fetch and a body fetch, and the guard ran against only the first (Zafran). Unless the file about to run is checked, immediately before it runs, against the file that was checked, different code runs with the safeguard’s approval.

Exhibit 1Detection vs pre-execution check

A pre-execution check means checking, before a model's code runs, that the code and weights loading are the ones that were checked and that the publisher is who it claims, and keeping a record. Detection means researchers finding and reporting the flaw. Dates are those each party reported or published.

Pre-execution check · not known from the disclosuresAfter the fetch and immediately before execution, check that the code and weights loading match what was checked
What was confirmedSubstituted code ran with the guard's approval
All three CVEs bypass trust_remote_code
Detection · researchers found itZafran reported it; 0.38.0 closed the known bypass paths
2026-03-19
Zafran reports the first two
2026-05-01
Diffusers 0.38.0 fixes them
2026-07-27
Zafran publishes the detail
2026-08-03
Coverage spreads

What got through

What got through
Loading a custom pipeline through DiffusionPipeline.from_pretrained. Once what the guard inspected was made to diverge from what actually loads, the substituted code ran with the “safe” status the guard had already conferred (Zafran).
What was stopped
Nothing. The trust_remote_code check ran, but it covered only the first request, the config (Zafran).
How the divergence is made
In the race-condition variant (CVE-2026-45804), the config is swapped in the window after the check and before the body fetch. The other variants need no timing: they create the same divergence through the default resolution of None.py, cross-repository pipeline loading, loads from a local snapshot, or malicious custom components (Zafran).
What reached the receiving side
In general, the side loading a model receives a name, a model card, a download count, and the fetched files. None of those show the provenance of the code about to run. The substitution happens inside the trusted distribution path itself.
Not disclosed
Whether, and in how many environments, a malicious repository was actually loaded. As of this Brief’s publication, no widespread in-the-wild exploitation has been reported.

Pre-execution check

Whatever the route, the condition for telling them apart is that, after the fetch completes and immediately before execution, the side loading the model checks that the code and weights actually loading are the ones that were checked, issued unaltered by the publisher they claim.

The core of this case
Unless the file about to run is checked, immediately before it runs, against the file that was checked, different code runs with the safeguard's approval.
Who approves
The model’s publisher, and the user or organization that decides whose models may be loaded. A repository’s location, reputation, or download count is not an approval.
Where it is checked
After the fetch completes, immediately before the code runs. What is checked is the hash of the code and weights that actually load, not the model card or the name. Anything that does not match is held, not loaded.
What is recorded
Which code and weights were loaded (or held), on which publisher’s confirmation, and when. Later, it shows which environment ran what.

The guard was running and refused custom code by default. What was missing is the layer that checks that the artifact seen at the moment of the check is the artifact run at the moment of execution. It has the same shape as Brief 116 (a fake OSS privacy filter), where trending and download counts stood in for provenance, and Brief 090 (a fake AIR agent skill), where contents changed after passing a scanner. Here the target changed between check and execution.

What Lemma does

Lemma puts the pre-execution check immediately before a model’s code runs. It does not tell good models from bad or judge whether code is dangerous; before execution, it checks that the code and weights actually loading match what a verified publisher issued.

Industries and operations to watch

IndustryAI
Organizations that fetch models from public repositories such as Hugging Face and load them in production AI pipelines.
IndustryDevelopers & agent operations
Developers and organizations that load models, including custom pipelines, inside CI/CD.

Current controls vs Lemma

The route in this case is a divergence between what the guard checked and what loads afterwards, through variants that use timing and variants that do not.

ControlConfig swapped in a timing window (CVE-2026-45804)Divergence without timing (None.py, cross-repository, local snapshot)
trust_remote_code (off by default)Not effectiveNot effective
Upgrading to 0.38.0 (checks moved to the dynamic-module loading chokepoint)EffectiveEffective
Pinning repository revisionsPartialPartial
Lemma (pre-execution check)EffectiveEffective

trust_remote_code was bypassed in all three CVEs. Diffusers 0.38.0 moved the security checks to the dynamic-module loading chokepoint, so that what is checked and what runs sit at the same point, closing the known bypass paths; it does not reach environments that have not upgraded. Pinning revisions is recommended, but in the parallel transformers flaw Zafran disclosed, a pinned commit hash failed to propagate, letting malicious code be swapped in after trust_remote_code approval. Lemma checks the code and weights that actually load, not the name or location, before they run. A record of each load is also kept, so which environment ran what can be confirmed later.

Note: Lemma’s check works only when it is built into the step that loads the model, and the approved publishers and the hashes of code and weights allowed to run are managed outside the loading side. If an approved publisher itself issues malicious code, it can pass. Lemma does not change Diffusers itself. The table compares what each control checks; it does not show whether this incident would have been stopped. Lemma does not detect or prevent intrusions.

CheckChecklist

Three things to confirm for organizations that load models

  • Do you decide whose models may be loaded, and confirm that a model was issued by that publisher separately from its name and download count?
  • Have you upgraded Diffusers to 0.38.0 or later and pinned the revisions of the repositories you load?
  • Do you confine the model-loading process to a scope of permissions that does not presume code execution?

Facts and timeline

Affected product
Hugging Face’s Diffusers, a library for diffusion models. Anyone calling DiffusionPipeline.from_pretrained with custom pipelines is affected; loading a malicious model repository quietly executes attacker code. Roughly seven million downloads a month, close to 200,000 a day.
Discovered by
Security firm Zafran (Gal Zaban and Ido Shani of Zafran Labs), under the collective name FaceHugger.
Vulnerabilities
CVE-2026-44827 (CVSS 8.8): code injection via the default-resolved filename None.py loaded as custom pipeline code. CVE-2026-45804 (CVSS 7.5): a race condition between the hf_hub_download and snapshot_download calls, with the configuration rewritten in between. CVE-2026-44513 (CVSS 8.8): three further variants sharing the same root cause: cross-repository pipeline loading, loads from a local snapshot, and malicious custom components.
The bypass chain (Zafran)
(1) A model download is split into a config fetch and a body fetch, two HTTP requests. (2) The trust_remote_code check applies only to the first, the config. (3) What the guard inspected is made to diverge from what actually loads. (4) The substituted code runs with the “safe” status the guard already conferred.
Race-condition window (Zafran)
Zafran measured the swap window at roughly 0.3 seconds, and the exploit needs an uncached first download. Even so, Zafran notes that on a heavily used repository an attacker can still win often enough by briefly publishing a malicious config and then reverting it.

Glossary
trust_remote_code — The safeguard built to stop unreviewed custom code from running. It is off by default (False), refusing custom code.
TOCTOU — Time-of-check to time-of-use: if the target can change after it is checked, the check stops meaning anything.

Timeline

  • Zafran reports the first two flaws to Hugging Face.
  • Diffusers 0.38.0 ships with the fix.
  • The CVEs are published following responsible disclosure.
  • Zafran Labs (Gal Zaban, Ido Shani) publishes the technical detail.
  • The Hacker News, Cybersecurity News and others report on it, and coverage spreads.

All three CVSS scores are the assessment of the CNA, GitHub. NVD’s own evaluation status differs by CVE: as of writing, CVE-2026-44827 is Analyzed, CVE-2026-44513 is Modified, and CVE-2026-45804 is Awaiting Analysis. This was responsible disclosure; as of publication no widespread in-the-wild exploitation has been reported. What has not been disclosed does not mean there were no controls.

After disclosure

  • Diffusers: 0.38.0 relocated the security checks to the dynamic-module loading chokepoint, so that what is checked and what is executed are the same object, closing the known bypass paths. Users are advised to upgrade and to pin repository revisions.
  • transformers: Zafran also disclosed a parallel flaw in Hugging Face’s transformers, where a pinned commit hash fails to propagate, letting an attacker swap in malicious code after trust_remote_code approval.
  • Earlier comparable cases: An equivalent trust_remote_code bypass in vLLM in March 2026, and InstructLab hardcoding trust_remote_code=True in April. Loading a model can amount to executing code beyond diffusion models.

Sources

  1. primary, vulnerability recordsNVD CVE-2026-44827 — https://nvd.nist.gov/vuln/detail/CVE-2026-44827 / CVE-2026-45804 — https://nvd.nist.gov/vuln/detail/CVE-2026-45804 / CVE-2026-44513nvd.nist.gov/vuln/detail/CVE-2026-44513
  2. primary, fix releaseHugging Face / GitHub “Diffusers 0.38.0”2026-05-01 · github.com/huggingface/diffusers/releases/tag/v0.38.0
5 more (reporting, analysis)
  1. independent reportingThe Hacker News Ravie Lakshmanan, “Hugging Face Diffusers Flaws Could Let Model Repositories Execute Arbitrary Code”2026-08-03 · thehackernews.com/2026/…
  2. independent reporting, technical detailInfosecurity Magazine Alessandro Mascellino, “Bugs in Hugging Face Diffusers Bypass Custom Code Safeguard”2026-07-28 · infosecurity-magazine.com/news/hugging-face-diffusers-trust
  3. independent analysisCybersecurity News Guru Baran, “Hugging Face Diffusers Vulnerabilities Enable Remote Code Execution Through Malicious AI Models”2026-08-03 · cybersecuritynews.com/hugging-face-diffusers-vulnerabilities
  4. earlier sibling case, independent analysisRAXE Labs “RAXE-2026-044: vLLM Hardcoded trust_remote_code Bypass” (CVE-2026-27893, 2026-03-27)raxe.ai/labs/advisories/RAXE-2026-044
  5. earlier sibling caseTheHackerWire “InstructLab RCE via Malicious HuggingFace Models” (CVE-2026-6859, 2026-04-22)thehackerwire.com/instructlab-rce-via-malicious-huggingfa…

References: “The last layer left for cyber defense in the age of AI”

The same method elsewhereSee all 31 "Supply chain" cases

This Brief sets out, from disclosed facts, what organisations in a similar position can check. It is not guidance on individual losses or procedures.

This material is a structured analysis of public information; it is not an audit, diagnosis, or recommendation for any specific organization.

Cite this Brief

Lemma Critical Team. (2026).
"Hugging Face Diffusers "FaceHugger": loading a model was enough to run arbitrary code (Zafran research, CVE-2026-44827 et al.)".
Lemma Critical Brief No.121. Lemma / FRAME00, Inc.
https://lemma.frame00.com/critical/briefs/121-hugging-face-diffusers-toctou/
Read nextNext
All Briefs →
Lemma

If it can't be verified,
it doesn't enter your operation.

Lemma is a pre-execution check: logins, payments, records and publishing that look genuine are checked before they run, with cryptographic proofs the receiving side verifies without asking the issuer. Detection stays; the check sits in front of it.