Skip to main content
AI Security

Hugging Face Diffusers Security: CVE-2026-44827 Guide 2026

BT

BeyondScale Team

AI Security Team

12 min read

Hugging Face Diffusers runs inside image generation pipelines at enterprises ranging from media companies to financial services firms, handling production workloads across FLUX, Stable Diffusion XL, and domain-specific fine-tuned models. In August 2026, three critical vulnerabilities collectively called FaceHugger revealed that the library's trust_remote_code security gate was broken in multiple ways, allowing arbitrary code execution during routine model loading without the caller ever setting trust_remote_code=True. This guide covers all three CVEs, explains exactly why SafeTensors does not protect against them, and gives security teams a concrete hardening checklist they can act on today.

Key Takeaways

    • CVE-2026-44827 (CVSS 8.8): A Python string interpolation bug lets a repository file named None.py bypass the trust_remote_code gate and execute code silently during any standard DiffusionPipeline.from_pretrained() call
    • CVE-2026-44513 (CVSS 8.8): Three separate code paths in custom pipeline loading let cross-repository and local snapshot sources bypass the security gate entirely, even with trust_remote_code=False
    • CVE-2026-45804 (CVSS 7.5): A TOCTOU race condition between two non-atomic HTTP download calls creates an approximately 0.3-second window for an attacker to swap malicious config into a repository mid-download
    • All three vulnerabilities are fixed in Diffusers 0.38.0 (released May 1, 2026); any earlier version is vulnerable in production
    • SafeTensors format does not protect against FaceHugger because the attack targets custom pipeline Python code, not model weight files
    • Enterprise controls beyond patching: version pinning, network egress restrictions, internal model registries, pre-deployment scanning with ModelScan or HiddenLayer, and AI Bill of Materials generation

Why Diffusers Matters to Enterprise Security Teams

The Hugging Face Diffusers library handles image, video, and audio generation using diffusion models in PyTorch. It wraps text encoders, UNet architectures, variational autoencoders, and noise schedulers into a single DiffusionPipeline class that enterprise teams deploy for FLUX pipelines, Stable Diffusion XL for marketing and product imagery, ControlNet for design workflows, and domain-specific fine-tuned models.

The library downloads approximately 7 to 8 million times per month, with around 200,000 new installations per day. It ships embedded inside production container images, CI/CD systems, and cloud inference pipelines. Microsoft, Amazon, and NVIDIA have all built infrastructure integrations on top of it.

The central loading function is DiffusionPipeline.from_pretrained(). When called with a Hugging Face Hub repository identifier, it reads the repository's model_index.json to determine the pipeline class, then downloads all required configuration and weight files. The trust_remote_code parameter was the library's intended security gate: passing trust_remote_code=False (the default) was supposed to block any repository-supplied Python code from executing locally. The FaceHugger CVEs show, in detail, how that gate failed across multiple code paths.

The broader context matters here. In July 2026, the Hugging Face Hub itself was breached, exposing private model artifacts and access tokens for thousands of organizations. That incident demonstrated that repositories from reputable organizations can be compromised. The FaceHugger CVEs add another layer: even a standard read-only call to from_pretrained() can execute attacker code if the library version is out of date, regardless of repository reputation.

For teams already running open-source AI model supply chain controls, Diffusers presents a distinct threat surface from Transformers. The pickle and SafeTensors hardening guidance for Transformers models does not address the pipeline code execution paths that FaceHugger exploits.

CVE-2026-44827: The None.py Bypass (CVSS 8.8)

The most subtle of the three vulnerabilities exploits a Python string interpolation quirk inside the _resolve_custom_pipeline_and_cls function.

When a caller does not supply a custom_pipeline argument, the parameter defaults to Python's None. The library constructs the pipeline filename using an f-string: f"{custom_pipeline}.py". Python evaluates None as the literal string "None", producing "None.py" as the target filename.

An attacker who publishes or compromises a Hugging Face Hub repository can include:

  • A standard-looking model_index.json that passes all integrity checks
  • A file named None.py containing a Python class subclassing DiffusionPipeline with arbitrary malicious code
Any caller who runs DiffusionPipeline.from_pretrained('attacker/repo') with no custom pipeline arguments will silently download and execute None.py. The trust_remote_code gate is never consulted because the code path does not look like a custom pipeline request.

In practice, the victim only needs to call from_pretrained() on a repository the attacker controls or has compromised. A developer copying a model identifier from a forum post, model card, or Slack message is all it takes. The attack leaves no unusual flags in application code that a code review would catch.

Fix in Diffusers 0.38.0: The security gate was moved from DiffusionPipeline.download() to get_cached_module_file() in src/diffusers/utils/dynamic_modules_utils.py. This is the single chokepoint that all dynamic module loading paths must pass through, so the gate now applies regardless of how loading was triggered.

CVE-2026-44513: Cross-Repository and Local Snapshot Bypasses (CVSS 8.8)

CVE-2026-44513 covers three distinct exploitation variants sharing the same root cause: the trust_remote_code security gate lived inside DiffusionPipeline.download() rather than at the actual module-loading call site, so multiple code paths bypassed it entirely.

Variant 1: Cross-repository custom pipeline. An attacker supplies a custom_pipeline pointing to a different repository than the one being loaded:

DiffusionPipeline.from_pretrained(
    'legitimate/repo-A',
    custom_pipeline='attacker/repo-B',
    trust_remote_code=False
)

The security gate evaluated repo-A's file list, not repo-B's. The pipeline.py from repo-B was loaded and executed without any check against the intended security parameter.

Variant 2: Local snapshot with Hub custom pipeline. When loading from a local directory path, the library takes a different code branch that never calls download() at all:

DiffusionPipeline.from_pretrained(
    '/local/snapshot/path',
    custom_pipeline='attacker/repo-B',
    trust_remote_code=False
)

Because the local-path branch skips download(), the security gate is never reached. The remote custom pipeline from repo-B executes without restriction.

Variant 3: Local snapshot with local custom components. Attacker-controlled local Python code in a snapshot directory can execute through custom component loading paths that also bypassed the gate.

All three variants were closed in 0.38.0 by raising ValueError before any module loading occurs when trust_remote_code=False and a custom pipeline is involved, regardless of loading path. This is an important architectural shift: the library now rejects the operation at the intent-declaration level rather than trying to gate each individual code path.

CVE-2026-45804: TOCTOU Race Condition in Two-Phase Downloads (CVSS 7.5)

A time-of-check to time-of-use (TOCTOU) race condition exists in the model download sequence because the library makes two separate, non-atomic HTTP requests to the Hugging Face Hub:

  • hf_hub_download: fetches model_index.json and configuration files; the security gate runs here
  • snapshot_download: fetches remaining artifacts from the cached state of the repository
  • Both calls resolve the repository's default branch to the current HEAD at the moment of the request. There is no atomic lock or commit-hash binding between them. An attacker who controls or has compromised the target repository can execute this sequence:

  • Present clean content for the first call, passing the security gate
  • Push a malicious config containing a None.py reference or custom pipeline injection between the two HTTP calls
  • The second call loads from a cache or makes a fresh request that fetches the modified content
  • Revert the malicious push immediately to reduce forensic evidence
  • Security researchers measured the exploitation window at approximately 0.3 seconds. This is achievable against frequently-accessed repositories where parallel download operations occur from multiple clients. In CI/CD pipelines where every fresh container build pulls from the Hub, this window opens on every build.

    The vulnerability only affects uncached first-time downloads. Subsequent loads from a stable local cache are not vulnerable. But in environments where container images do not cache model weights, the exposure recurs continuously.

    Fix in 0.38.0: Enforcement was moved to be co-located with the dynamic module loading operation, tightening validation across remote, cached, and local sources as part of the same code path rather than as a pre-download check.

    Why SafeTensors Does Not Protect Against FaceHugger

    A common misconception among MLOps teams is that using SafeTensors format provides protection against AI model supply chain attacks. SafeTensors was specifically designed to eliminate pickle deserialization vulnerabilities: it stores only raw tensor weights and numerical data, with no executable code embedded in the weight file. This is a real improvement over PyTorch's pickle-based .pt format.

    The FaceHugger attacks do not touch the weight file format. They exploit the Python code loaded as part of the pipeline class definition. A malicious repository can include:

    • Legitimate SafeTensors weights that pass all integrity and scanning checks
    • A malicious None.py or pipeline.py that executes during from_pretrained()
    The weight file is clean. The attack runs through the pipeline class loading mechanism before the weights are ever read.

    This gap exists in model scanning tools as well. ModelScan by Protect AI and HiddenLayer's Model Scanner detect malicious code in serialized weight files, including pickle exploits and embedded callbacks. They do not analyze custom pipeline Python code loaded via from_pretrained(). A complete defense requires both weight scanning and explicit controls on custom pipeline code execution.

    For compliance teams referencing the OWASP Machine Learning Security Top 10 ML06: Supply Chain Attacks, this distinction matters: the supply chain attack surface covers the full pipeline definition, not just the serialized model artifact.

    Enterprise Hardening Checklist

    Immediate Actions

    Upgrade all Diffusers installations to 0.38.0 or later. This is the only complete fix for all three CVEs.

    pip install --upgrade "diffusers>=0.38.0"

    Inventory every location where Diffusers is installed: production containers, CI/CD build images, development environments, JupyterHub instances, and batch inference jobs. A targeted search across infrastructure repositories surfaces pinned versions:

    grep -r "diffusers" requirements*.txt Dockerfile* setup.py pyproject.toml

    Audit all trust_remote_code=True usage. Search all application code for this flag and document every instance. Each approved use should include: a mandatory justification, a specific commit hash pinned in the revision parameter, and confirmation that the repository is internally controlled or externally audited.

    # Acceptable pattern after security review:
    DiffusionPipeline.from_pretrained(
        'org/model',
        trust_remote_code=True,
        revision='a3f7b2c1d4e5f6a7...'  # pinned commit
    )

    Infrastructure Controls

    Restrict outbound Hub access from inference containers. Use egress firewall rules or cloud VPC service policies to limit which Hugging Face Hub repositories inference containers can reach. Maintain an approved repository allowlist and block all other Hub traffic from production inference nodes. This limits the blast radius of a compromised or malicious repository regardless of library version.

    Mandate an internal model registry. Require all production models to pass through an internal staging registry before deployment. The workflow: pull from Hub in an isolated environment, scan with ModelScan, review any custom pipeline Python code in non-standard repositories, then publish to the internal registry. Production inference containers pull only from the internal registry.

    pip install modelscan
    modelscan -p /path/to/downloaded/model/

    Pin Diffusers versions across all environments using lockfiles. Version pinning prevents uncontrolled upgrades and also prevents accidental downgrades to vulnerable versions when dependency resolution occurs.

    # requirements.txt
    diffusers==0.38.0

    Monitoring and Detection

    Log all from_pretrained() calls with structured metadata. Instrument model loading code to emit logs including: the repository identifier, whether the source is Hub or local path, the trust_remote_code setting, any custom_pipeline argument, and the process or user triggering the call. Route these logs to your SIEM.

    Alert on trust_remote_code=True in CI/CD pipelines. Add a pre-deployment pipeline step that scans code diffs and build logs for trust_remote_code=True and blocks the deployment pending security review.

    Integrate model scanning as a blocking CI/CD gate. Any model that fails a ModelScan check should block deployment. This catches pickle deserialization threats in weight files as a complementary layer to the pipeline code controls.

    Compliance Alignment

    The NIST AI Risk Management Framework GOVERN 6 function requires policies covering third-party software dependencies. Running Diffusers versions below 0.38.0 after public CVE disclosure fails this control. The MAP 4 function requires risk mapping for all AI system components, which includes open-source library versions and their CVE status.

    For enterprises running image generation pipelines on AWS or Azure, this supply chain risk belongs in your AI Bill of Materials (AI-BOM). CycloneDX v1.5 and SPDX 3.0 both support ML-BOM extensions for tracking model artifacts, framework versions, and custom pipeline code. Generating an AI-BOM for every production Diffusers pipeline creates the traceability record required by NIST AI RMF and current EU AI Act governance requirements.

    Our AI security assessment covers the full Diffusers deployment surface: version auditing, trust_remote_code usage review, custom pipeline code inspection, model registry configuration, and CI/CD gate validation for teams running image generation pipelines in production.

    What Competitors Cover and Where the Gap Is

    HiddenLayer's Model Scanner supports 35+ model formats and detects pickle deserialization exploits and architectural backdoors in model weights. Lakera Guard focuses on prompt injection at inference time. Neither provides a dedicated playbook for the FaceHugger code execution vulnerabilities in the Diffusers loading pipeline.

    The SERP gap is clear: The Hacker News, Infosecurity Magazine, and CybersecurityNews covered the CVE disclosure as news items. No AI security vendor published an enterprise hardening guide covering all three variants, the SafeTensors misconception, or the CI/CD integration controls that make the patch durable.

    MLOps teams at enterprises who saw the CVE news and patched to 0.38.0 have solved the immediate problem. Teams that have not also implemented version pinning, egress controls, and model scanning will be in the same vulnerable position when the next Diffusers CVE arrives.

    Conclusion

    The three FaceHugger CVEs in Hugging Face Diffusers follow a recognizable pattern in library security: a security gate placed at the wrong abstraction layer fails when code takes an alternative path to the same outcome. The trust_remote_code parameter was designed to prevent arbitrary code execution, but because the gate lived inside a download helper function rather than at the actual module loading site, multiple code paths bypassed it. Layering a TOCTOU race condition on top created an attack surface that affected every enterprise running unpatched Diffusers.

    The immediate fix is clear: upgrade to Diffusers 0.38.0. The durable fix requires building supply chain controls that contain the next library-level vulnerability: version pinning enforced at the registry level, egress restrictions on Hub access, an internal model registry with pre-deployment scanning, and AI-BOM generation for every production pipeline.

    Security teams that build those controls now will spend far less time scrambling when the next CVE drops. Teams that treat this as a one-time patch will repeat the same cycle.

    Run a BeyondScale Securetom scan to surface unapproved Diffusers versions and unreviewed Hub repository connections across your AI infrastructure automatically, or book an AI security assessment to get a full review of your diffusion model pipeline security posture.

    AI Security Audit Checklist

    A 30-point checklist covering LLM vulnerabilities, model supply chain risks, data pipeline security, and compliance gaps. Used by our team during actual client engagements.

    We will send it to your inbox. No spam.

    Share this article:
    AI Security
    BT

    BeyondScale Team

    AI Security Team, BeyondScale Technologies

    Security researcher and engineer at BeyondScale Technologies, an ISO 27001 certified AI cybersecurity firm.

    Want to know your AI security posture? Run a free Securetom scan in 60 seconds.

    Start Free Scan

    Ready to Secure Your AI Systems?

    Get a full security assessment of your AI infrastructure.

    Book a Meeting