Transformers path traversal writes files anywhere (CVE-2026-9856)
Loading and saving a crafted Hugging Face model lets an attacker write files outside its folder. NVD's affected range is wrong — upgrade to 5.10.1 or later.
Table of contents
Loading and saving a crafted Hugging Face model lets an attacker write files outside its folder. NVD's affected range is wrong — upgrade to 5.10.1 or later.
A vulnerability has been found in Transformers, the Hugging Face Python library that sits at the heart of almost every AI project. Load a booby-trapped AI model and then save it, and an attacker can have files of their choosing written outside the folder you meant to save into. It is tracked as CVE-2026-9856, scored 7.1 out of 10.
Transformers is downloaded about 177 million times a month and has over 160,000 GitHub stars. It is fair to say that nearly all Python code touching AI models passes through it, directly or indirectly.
The catch is that the public record on this one is broken. The US national vulnerability database gives two different affected-version ranges on the same page, the release it points to as the fix has already been withdrawn, and the link to the original report has been dead since the day the entry went live. Below we pin each of those down in turn. The short answer: upgrade to 5.10.1 or later.
The published affected-version range is wrong
There is no getting past this before anything else. Within a single page on NVD (the vulnerability database run by the US National Institute of Standards and Technology), the answer is given two different ways.
| Where it appears | Affected versions | Verdict |
|---|---|---|
| Description text | 5.8.0.dev0 and earlier | Wrong |
| Structured range data | Below 5.10.0 | Correct |
Settling it is a matter of opening the packages. For this article we pulled the release files for each version from PyPI and compared the code inside. The 5.9.0 package does not contain the fix; the 5.10.0 package does. Checking on the GitHub side which tags include the fix commit gave the same answer.
The string "5.8.0.dev0" is the kind of number attached to an in-development build. It looks like the version of the development build the researcher happened to be running when they reported the bug, copied straight into the description. Trust that number, conclude "we are on 5.9.0 so we are fine," and you stay exposed.
And the first fixed release, 5.10.0, was pulled
There is a second trap here. Version 5.10.0, the first release to carry the fix, was yanked about 20 minutes after publication. PyPI now flags it as withdrawn.
The reason had nothing to do with the vulnerability. The maintainers' release notes say it was pulled because it had been published from a broken branch, adding that this is what happens when you rush a release, and apologising. 5.10.1 went out immediately after.
So advice to "upgrade to 5.10.0 or above" does not survive contact with reality. A yanked release will not be picked by a normal install. Pin 5.10.1 or later instead. The latest version at the time of writing is 5.14.1.
The hole was open for about 12 and a half months
We also traced how long the flaw had been there. The offending code arrived in 4.52.0, released on May 20, 2025; the previous release, 4.51.3, does not have it. The fix shipped on June 3, 2026, which means the bug sat in published releases for roughly 12 and a half months.
Any project that froze its environment on a 4.52.x or 5.0-5.9 build during that window is still affected today.
Downloading is harmless. Saving is what triggers it
The mechanism is simple. An AI model can carry several "chat templates," settings that define how a conversation is assembled. They live in the config file tokenizer_config.json as a list of name-and-content pairs.
On save, Transformers used that "name" directly as the filename. If the name contained something like ../../ to climb up a directory level, it was joined on and written out as-is. That is how the write escapes the folder.
The order of events matters here.
Loading a model (from_pretrained()) on its own does nothing. At that point the attacker's chosen name is merely read into an internal list. The actual write happens when you later save (save_pretrained()). Writing templates out as separate files is on by default.
You might think you never call save explicitly, but that is not a safe assumption. The Transformers training helper (Trainer) calls the save routine internally every time it writes a checkpoint. Grab a public model, fine-tune it, save progress along the way; that entirely ordinary workflow sets it off. This is the most realistic path to exploitation.
The affected code is the save logic in the text-handling component (the tokenizer) and in the component that handles images and audio alongside text (the processor). The fix adds three lines that check whether the destination stays inside the intended folder and refuse the write if it does not.
Who would exploit this, and what they get
The targets are people who pull down public AI models and then fine-tune or re-save them in their own environment. Researchers, machine learning engineers, and anyone evaluating models inside a company. Hugging Face hosts around 2.96 million public models, and anyone can upload their own.
All an attacker has to do is publish a model that looks perfectly normal and plant a doctored name in its config file. Then they wait for someone to try it out and save it. No stolen passwords, no network intrusion required.
The damage is that files quietly appear in places you did not intend. Config files in a training environment can be rewritten, files can be dropped into someone else's work area on shared storage, or settings that get read next can be swapped out. From a company's point of view, a single model brought in from outside becomes a way to contaminate the whole compute environment.
What an attacker can write, and what they cannot
This part deserves precision. This is not a takeover bug. The severity breakdown rates information disclosure as none, tampering as high, and denial of service as low. It is not rated as allowing arbitrary code execution.
Here is what does work. The attacker fully controls the contents of the file. As for where it lands, both relative paths that climb upward and outright absolute paths go through.
The limits are equally clear. Every file written out gets a .jinja extension. The attacker cannot choose the end of the filename. That rules out overwriting, under its own name, a startup script that runs automatically at login or a file holding keys.
We first thought this might be pushed into code execution by dropping a file of the sort Python loads automatically at startup, since a supply-chain poisoning case we covered previously worked exactly that way. But with the extension fixed here, that route is closed. Having confirmed that, we decided against writing this up as "your server is instantly taken over."
Even so, being able to place a file with arbitrary contents at an arbitrary location is plenty dangerous on its own. Overwriting config files, or slipping a file into a location some other process reads, both work. Neither underplay it nor overplay it: the accurate reading is "one file, with contents of the attacker's choosing, created anywhere on disk."
A proof-of-concept is still sitting on Hugging Face
One more thing we turned up while researching this. A model repository built to demonstrate the vulnerability is still publicly available on Hugging Face.
The repository is named etwithin/transformers-pathtraversal-poc and was created on March 6, 2026, roughly three months before the fix shipped. Looking at its config file, the template name is written as an absolute path, so running it produces a marker file. The contents are just proof-of-concept text, nothing destructive.
Hugging Face documents a scanning system that inspects uploaded files on every commit. That scanning, though, mainly targets file formats capable of carrying embedded malicious code. What is going on here is nothing more than some characters typed into a name field inside a plain text config file. It is not code, and it is not a dangerous file format. We have also covered a case where the model-scanning tool itself could be bypassed, but this time the payload does not even take a shape the scanner looks at.
Dependabot stays quiet, because the reporting channel itself shut down
This is the most awkward part of the whole story. The vulnerability is absent from the automated detection pipeline entirely.
We checked, and it is not registered in GitHub's global advisory database or in OSV. No advisory page for it was created in the Transformers repository either. The Red Hat, Debian and Ubuntu trackers all come back empty. Dependabot, and the usual tools that scan Python dependencies, currently say nothing at all.
That is odd. The three most recent Transformers vulnerabilities (CVE-2026-5241, CVE-2026-4372 and CVE-2026-1839) all came in through the same reporting route, and all three got advisory pages. Only this one did not.
huntr ended its open-source programme
Follow the reason and you arrive at huntr, the platform that brokered the report. It billed itself as the world's first bug bounty platform dedicated to AI and machine learning, and was acquired by Palo Alto Networks in July 2025.
In an announcement on June 8, 2026, huntr said it was formally ending its open-source vulnerability programme. According to the accompanying FAQ, new submissions closed on June 30 and all submissions were frozen on July 31. Outstanding reports will not be processed further and no bounties will be paid. Open-source maintainers are told to move to GitHub's advisory features.
This CVE identifier was published on August 2. Two days after the freeze.
The reference link was dead on day one
The upshot is that the huntr report page NVD cites as its technical source returns a "this page does not exist" error when you visit it. We confirmed this from several directions.
And it is not just this entry. Every huntr report page referenced by other, older CVEs that we checked was in the same state. Even the official disclosure policy page and the official advisory index registered for huntr as a CVE-issuing organisation are gone. They did not merely stop accepting reports; the archive of past ones has been taken down too.
Meanwhile, the Transformers security policy document still names huntr as the place to send reports, as of this writing.
In practical terms for readers, it comes to this. A vulnerability can carry a CVE number while the source you would use to verify it technically never existed in accessible form. We were able to reconstruct the details here only because the pull request and diff for the fix were public; without those, all that would remain is the number "7.1." We found a similar discrepancy in the record on a separate case the same day, and the machinery that hands out these identifiers keeps looking shaky.
The list of vulnerabilities known to be under active attack published by the US government's CISA does not include this one (the latest edition is dated July 29 with 1,656 entries, predating the CVE assignment). An EPSS score predicting exploitation likelihood has not been calculated yet either.
The risk in simply running a model you downloaded
This is not a one-off defect; it belongs to a clear lineage. The act of loading a publicly published AI model keeps turning out to be an entry point for attacks.
Transformers itself has form. In June 2026 a flaw allowing code execution through a particular model-loading path was disclosed (CVE-2026-5241), and in April a similar flaw in the training machinery (CVE-2026-1839). Before those, several bugs abusing model-file loading had already surfaced.
The same thing happens in neighbouring components. We have covered an SGLang case where a malicious AI model hands over the server, a vLLM case where a setting meant to fail safe did nothing, and a case of poison mixed into the distribution channel for an AI component. How a flaw in one component cascades downstream is laid out in our piece on chain-reaction risk in open-source components.
The common thread is that the assumption "a model is data, not code" does not hold. Models come with settings, and settings change how the loading program behaves. When a string inside those settings becomes a filename verbatim, as it does here, it has stopped being input and become an instruction. Checking whether the source you downloaded from is trustworthy takes exactly as much care as it does when you pick up an executable.
The bottom line
Update Transformers to 5.10.1 or later. The "5.8.0.dev0 and earlier" in the NVD description is wrong; everything below 5.10.0 is affected. Because 5.10.0, the first release with the fix, was withdrawn right after publication, pin 5.10.1 or later.
You are exposed if you load models obtained from outside and then save them. Loading alone does not trigger anything, but a fine-tuning workflow that writes checkpoints runs the save routine automatically. If that sounds like you, avoid models from sources you cannot vouch for until you have upgraded.
The thing most worth remembering here is that the reason automated detection is silent has nothing to do with the bug and everything to do with a reporting channel shutting down. The technical source disappeared before the entry was even published, and no advisory page was ever created. How fast a vulnerability becomes public and how fast it reaches the scanner on your own machine are two different speeds, and plumbing problems can widen the gap easily. For components you cannot afford to have break, it pays to have a way of reading the maintainers' release notes directly, separate from waiting on your scanner to ping you.
Sources
- ▸ NVD - CVE-2026-9856
- ▸ CVE.org - CVE-2026-9856 (Path Traversal in huggingface/transformers)
- ▸ huggingface/transformers PR #46191 - Fix path traversal when saving named chat templates (May 25, 2026)
- ▸ huggingface/transformers - the fix commit
- ▸ huggingface/transformers - Release v5.10.1 (explanation of the 5.10.0 yank) (June 3, 2026)
- ▸ PyPI - transformers
- ▸ huntr - Huntr 2.0: Stop Writing Reports, Start Breaking AI (announcement ending the OSS programme) (June 8, 2026)
- ▸ huntr - Huntr 2.0 FAQ (freeze schedule) (June 8, 2026)
- ▸ Hugging Face - Malware Scanning
- ▸ NVD - CVE-2026-5241 (a recent Transformers case)

Makoto Horikawa
Backend Engineer / AWS / Django