
CVE-2026-4372: Threat Model, Root-Cause Analysis, Replication & Detection
Defensive analysis of a critical remote code execution (RCE) bug in Hugging Face
transformers.
| Field | Value |
|---|---|
| Identifier | CVE-2026-4372 / GHSA-29pf-2h5f-8g72 |
| Component | Hugging Face transformers |
| Class | Remote code execution (CWE-94, code injection) |
| Entry point | AutoModelForCausalLM.from_pretrained(), when a model is loaded |
| Mechanism | An attention setting in the model's config.json (attn_implementation / _attn_implementation_internal) makes the library download and run attacker code |
| Key property | Bypasses trust_remote_code=False, the setting users rely on to stop exactly this |
| Fixed in | transformers 5.3.0 |
A user who deliberately left trust_remote_code=False to stay safe was still exposed.
Check the details below against the official sources before treating them as final:
Two trigger descriptions are in circulation:
config.json attention field (_attn_implementation_internal).kernels package, often installed through transformers[all].They are most likely the same path: the attention field names a Hub repository, and the
kernels package downloads and runs code from it. Treat the field names here as
provisional until the fix commit confirms them.
[ Model repo on the Hub ] untrusted source
│ config.json, tokenizer, weights, (code)
▼
[ Download to local cache ]
▼
[ Read config.json ] settings become a config object
▼
[ Pick model class + attention type ]
▼
[ Build model, load weights ]
▼
[ Model runs in the user's process, with the user's permissions ]
| # | Boundary | Guard that should apply |
|---|---|---|
| TB-1 | Hub → local disk | Trusted repos, pinning to a fixed commit |
| TB-2 | Config file → config object | Only allowing known, safe values |
| TB-3 | Config object → running code | trust_remote_code |
| TB-4 | Model → operating system | Sandbox, least privilege |
The bug is a failure at TB-3: a value from the config file reached code execution
without passing the trust_remote_code check.
In every case the victim only runs the normal call,
AutoModelForCausalLM.from_pretrained("<repo-id>").
trust_remote_code guards one way of running repo code: custom modeling_*.py files.
The attention setting was a second way that never went through that guard.
untrusted config.json attention setting
│
▼
"pick attention type" logic
│ never checks:
✗ ─────────────▶ trust_remote_code
▼
download + run code from the Hub (via `kernels`)
_ prefix) could still be set from an untrusted file.kernels) silently enabled the attack when installed, for example via transformers[all].Guard the dangerous action, not one route to it. Every path that can lead to "run code" must go through the same check.
The defence is one self-contained script, defence/safe_load.py.
Its function safe_from_pretrained() replaces from_pretrained() and runs four checks
before any model is loaded. If one fails, it raises UnsafeModelLoad and nothing is loaded.
| # | Check | What it does |
|---|---|---|
| 1 | Version | Refuses if transformers is older than 5.3.0. This is the real fix. |
| 2 | Kernels | On an old version, refuses if the kernels package is installed, since the attack needs it. |
| 3 | Config | Reads the model's config files and refuses if they contain a risky setting (see below). Hub models are checked and loaded at the same commit. |
| 4 | Remote code | Always sets trust_remote_code=False. Good practice only: this CVE bypasses it. |
An old version is refused at check 1. Checks 2 and 3 only run on an old version if the
lab-only option allow_vulnerable_env=True is set.
What check 3 blocks:
attn_implementation, _attn_implementation,
_attn_implementation_internal) that is not built in. Only eager, sdpa,
flash_attention_2, flash_attention_3 and flex_attention are allowed, so a value
like attacker-org/evil-kernel is blocked, even inside a nested sub-config._attn_implementation_internal, auto_map and custom_pipelines.config=, since it would skip the check.For Hub models, only the config files are downloaded, never weights or code. They are
downloaded at one fixed commit, and the model is then loaded from that same commit,
so the files cannot be swapped between the check and the load. After reviewing the
warnings, a person can override check 3 with accept_findings=True.
| Situation | What stops the attack |
|---|---|
transformers 5.3.0 or newer | Check 1 |
Old version, kernels installed | Check 2 |
| Old version, risky setting in config | Check 3 |
| Repo changed after it was checked | Check 3 (same commit checked and loaded) |
Limitation: check 3 only knows the settings listed above, so it cannot catch a new
attack. Upgrading to transformers>=5.3.0 is the only complete fix.
The detection component identifies potentially unsafe Hugging Face model configurations and vulnerable dependencies associated with CVE-2026-4372. It provides two independent detection mechanisms: static configuration scanning and dependency analysis.
Unlike the Defence component, these tools report potential security risks without loading models or executing untrusted code.
File: src/detection/static_detector.py
The static detector parses config.json files and recursively examines nested JSON objects and arrays for security-sensitive fields.
The following fields are monitored:
| Configuration Field | Detection Purpose |
|---|---|
_attn_implementation_internal | Internal attention configuration field associated with CVE-2026-4372 |
_experts_implementation_internal | Additional internal implementation field requiring review |
auto_map | May reference custom model implementation code |
custom_pipelines | May reference custom pipeline implementations |
Usage:
cd src/detection
python3 static_detector.py samples/suspicious_config.json
Example output:
[WARNING] samples/suspicious_config.json: review field '_attn_implementation_internal'