On 1 September 2026, CERT/CC published VU#456290 and GitHub published GHSA-x9r9-c232-4q39 for CVE-2026-80047 in Hugging Face Transformers. When code asked a model to use a custom generation method from a Hub repository, Transformers downloaded and cached that repository's custom_generate/generate.py before checking whether the user had agreed to run remote code.
Execution was still gated by consent. The file write was not. CERT/CC's concern is that the file persists in the module cache and could later be picked up during a trusted load. GitHub rates it 7.8, high.
What's affected
- Package:
transformerson PyPI. - Listed range: the GHSA and the CERT/CC note both list 4.49.0 through 5.8.1. Neither lists a fixed version. The CERT/CC note, last revised 22 September, says no vendor patch or advisory was available when it was written.
- What actually changed: pull request #48620, "Avoid unconditionally downloading remote hub file", was merged on 8 September 2026 as commit
cbc1651. We compared the source of several releases. In 5.17.0 (uploaded 9 September),generation/utils.pychecks that the file exists withhas_file()and only downloads it after the trust check. In 5.9.0, 5.12.0 and 5.16.1, the same function still callsget_cached_module_file()beforeresolve_trust_remote_code().
That gap matters for scanners. Versions 5.9.0 through 5.16.1 contain the old ordering but sit outside the published range, so a tool that reads only the advisory range will call them clean. The current release is 5.20.1.
How to check if you're exposed
Start with the version:
pip show transformers | grep -i ^version
python -c "import transformers; print(transformers.__version__)"
Treat 4.49.0 up to and including 5.16.1 as carrying the old behavior. Then check whether the vulnerable path is reachable. Two entry points call load_custom_generate():
model.generate(custom_generate="org/repo", ...)calls it with whatevertrust_remote_codeyou passed. On old versions, the file is fetched before the consent check raises. This is the path the advisory is about.from_pretrained(..., trust_remote_code=True)calls it only after you've already agreed to remote code, so the ordering bug doesn't change much there.
Search your code for the first pattern:
grep -rnE 'custom_generate\s*=' --include=*.py .
If the repo id passed to custom_generate is a constant you reviewed, exposure is low. If it comes from user input, a config file others can edit, or a model card, it's reachable.
Then look at what's already cached:
MODS="${HF_MODULES_CACHE:-${HF_HOME:-$HOME/.cache/huggingface}/modules}"
find "$MODS" -name 'generate.py' -print 2>/dev/null
ls -la "$MODS/transformers_modules" 2>/dev/null
Any generate.py from a repository you never chose to trust is the artifact this bug leaves behind.
What to do now
- Upgrade to
transformers5.17.0 or later. That release contains the fix even though the advisory doesn't name it. - Clear the modules cache on shared machines, CI runners and notebook servers. CERT/CC's workaround is to periodically inspect or clear
~/.cache/huggingface/modules. - Don't pass untrusted repo ids to
custom_generate. Keep an allowlist of reviewed repositories and pin a revision. - Give CI and inference jobs a fresh, per-job
HF_HOMEso one job's cached modules can't be reused by another. - Add a manual override in your vulnerability tooling for 5.9.0 through 5.16.1 if it relies on the GHSA range alone.
Why it matters
Remote code in model repositories is a supply chain channel, and trust_remote_code is the gate. The bug here was ordering: fetch, then ask. Other loading paths in Transformers, such as AutoModel and AutoTokenizer, already asked first, which is why the inconsistency stood out to the reporter.
There's a second lesson in the version data. When a maintainer fixes a bug without updating the advisory, the published range and the real fix drift apart. Advisory ranges are a starting point. Checking whether your code calls the affected function, and whether the fix is in the source you ship, gets you a better answer than the range alone.
Try it yourself
Run the grep above on one repository and count how many transformers imports actually reach custom_generate. Most projects that depend on Transformers never call it. That difference between "package present" and "function called" is what reachability analysis measures:
Click through it at your own pace, or open it full screen.
Quick check
Does CVE-2026-80047 let a malicious repo run code without consent?
Not directly. Execution was still gated by the trust check. The flaw is that the file was written to the module cache before consent, where it persisted and could be served during a later trusted load.
Which version contains the fix?
5.17.0, uploaded 9 September 2026. Pull request #48620 was merged the day before. The GHSA and CERT/CC note list no fixed version.
Is calling from_pretrained without trust_remote_code affected?
No. In the affected code, from_pretrained only calls load_custom_generate when trust_remote_code is true. The risky path is generate with a custom_generate repo id.
Sources
- CERT/CC VU#456290: Hugging Face Transformers library writes remote code to disk prior to consent check
- GHSA-x9r9-c232-4q39: Transformers downloads custom generation code before trust consent (CVE-2026-80047)
- huggingface/transformers pull request #48620
- transformers v5.17.0 generation/utils.py
- transformers v5.16.1 generation/utils.py
- transformers on PyPI