How Public llms.txt Files Let Researchers Run Code Inside Big Companies
Researchers registered unclaimed package names that official llms.txt files told AI agents to install, and code ran inside large companies within minutes. Why data is now code.
This article is published in English.
Sources: Data Became Code: We Ran Code Inside Fortune 500s Using Files They Published for AI Agents
When a published file becomes an order
A security research team reported that a machine inside a Fortune 500 company ran code they had published, and that it happened roughly four minutes after the code went live. Two further callbacks came within the hour. By their account nobody exploited a CVE, phished an employee or touched a network perimeter. The researchers registered a handful of names that official, HTTPS-served files, put out by the companies themselves, were already telling AI agents to use.
Those files were public and the names behind them were unclaimed. The agents did exactly what they were built to do. The same team also says that while scanning these files at scale they ran into a live attack already out in the open: a vendor's instruction file that pointed agents at confirmed malicious code. That case comes below.
First, the background.
Why llms.txt matters here
For most of the web's history a page on a site was only a page. A person might read it, a crawler might index it, and no one treated it as a command. That no longer holds.
Companies now put a new kind of file at the root of their sites, next to robots.txt: llms.txt, and sometimes a longer llms-full.txt. It isn't a sitemap and it isn't a legal notice. It works as a curated set of directions for AI agents covering what to read, which APIs to call, which packages to install and which domains to trust. The big model labs publish their own, and Google's Lighthouse tooling in Chrome DevTools now has an audit under "agentic browsing" that nudges sites to provide one. The number of these files is heading in one direction.
The team set out to learn how widely this instruction layer had spread. Their count: 8,565 llms.txt files on 6,214 live domains, out of about 15,000 catalogued companies. Large enterprises, tech giants, fintechs and defence contractors were among the publishers.
A typical file sends an agent to documentation, a changelog and a community forum, and then to an install line, something like a pip install for the company's SDK. It reads as helpful and official, and it comes from the company's own domain over HTTPS. An AI coding agent asked to integrate with that product will read the line and run it.
The follow-up question was almost embarrassingly plain: who actually owns that package name on PyPI? Case after case, the answer was nobody. The name sat in an official first-party file, and the package it pointed at had never been claimed. First come, first served.
The researchers checked a few more files, then hundreds, then most of them, and saw the same thing everywhere. Install instructions named packages and domains that no one had registered. In their words these were not "potentially vulnerable", merely available. It also isn't typosquatting. The names in the files are spelled correctly, so there's no typo for anyone to catch, because the registrations never happened.
How code ended up running inside large companies
The team picked a small set of package names that showed up in the llms.txt files of well-known firms and registered them on PyPI and npm. Each package carried one harmless phone-home, a minimal beacon reporting that an install had happened to infrastructure the researchers controlled. After that they waited.
The first callback landed in under four minutes. Concretely, somewhere inside a company worth several hundred billion dollars, an AI agent had read the llms.txt on a company site, found a pip install line and run it. The package came from PyPI as the file said, though it was the researchers' package. The second callback from a Fortune 500 company arrived inside an hour, and a few dozen more followed from startups and enterprises alike, some with security teams bigger than the researchers' whole professional network.
Their summary is that they didn't beat anyone's security, they abused a chain of trust.
How agents come across these files on their own
The experiment then asked how little prompting it takes. The researchers tried five frontier configurations across two agentic CLIs, gave each the same sentence 100 times, and put nothing in it except a vendor's name. The sentence asked the agent to use all of that vendor's docs to build and run a Node.js project with its SDK.
That was the whole prompt. It held no URL, no link to documentation and no mention of llms.txt. There was no prompt injection, no attacker in the loop and no social engineering. The agent located the instruction channel by itself, because tracking down a vendor's official documentation is exactly what it was built for. The team reports counting how many of the 100 runs per configuration went to llms.txt, saw the command and installed a package nobody had registered.
The packages were inert by design, only a beacon. Everything up to this point was controlled research. What follows is a separate incident turned up while the corpus was being analysed.
A case already live in the wild
One finding stopped the team cold, because it was already happening.
Clerk, an authentication vendor whose SDKs sit behind a large share of production Next.js apps, publishes documentation written for AI agents. An agent that follows that trail reaches Clerk's llms.txt guidance for an auth-protection fixer, which contains this command:
npx clerk-next-fix-auth-protection
The agent reads that and executes it, which is hardly surprising for guidance straight from the vendor.
The trouble isn't a misspelled package name. The bare command clerk-next-fix-auth-protection is the binary shipped inside Clerk's scoped package @clerk/eslint-plugin. The docs have agents install the scoped package first and then call the bare command. But if the bare command runs before the package is installed locally, npx looks the name up on the public npm registry, where Clerk never published it as a standalone package.
Someone else registered it instead. By the researchers' description the package has no functional code, but the moment it installs it fires hooks that send the installer's username, machine name, working directory and a timestamp to an outside server, on every install. It is catalogued as MAL-2026-11069 under CWE-506, embedded malicious code, and was flagged by Google's OSV.dev and Amazon Inspector. The documentation, the open slot and the blind execution would be identical whether the payload grabbed a username or dropped a full backdoor. The distribution mechanism is the vulnerability, and the payload is only a choice.
The research was disclosed to Clerk's security team, who responded quickly and fixed it. The write-up stresses that this is no criticism of Clerk. A third party registered the package, abusing npx name confusion, and Clerk had no control over that. The team presents it as a confirmed, in-the-wild example of a structural issue that touches any vendor publishing agent-readable documentation.
Why current controls may not notice
Every signal a security setup relies on points the wrong way here. An agent that meets an llms.txt sees a file served over HTTPS from the official domain, in a standard format meant for AI consumption, published by the company or by a partner it trusts. The agent has little reason to doubt any of that, since the file is the authority by design.
So when the file says to install an internal-looking tool, the agent doesn't stop to check whether the name belongs to the company. It doesn't inspect the PyPI namespace, and it doesn't notice that a documentation link points to a domain whose registration lapsed three months ago. It does what the file says.
Trust is also transitive. The llms.txt needn't live on the target company's site. Agents pull context from trusted third parties such as a partner's docs, a vendor's SDK reference or a community project's setup page. If the agent trusts that third party and the third party's file points at an unclaimed package, the chain works the same way.
Endpoint detection didn't blink either. To an EDR tool or a proxy, this looks like a developer running a legitimate package manager: a pip install against pypi.org, a domain every corporate proxy allows, with a coding agent the company deployed on purpose as the parent process. There is no anomaly and no alert. The failure sits upstream, in the gap between instruction and execution, and the endpoint can't catch it because it was never asked the right question.
Data turned into code
For decades content was consumed by people. Now AI agents are often the first to read, interpret and act on it. That is the category error the industry walked into together: the border between data and code has collapsed. Whatever sits on your website is no longer just content. It is operational input, effectively code running in someone else's environment with whatever privileges the agent holds.
That overturns an old assumption. Pages and docs used to count as low risk by definition because no one treated them as executable, so no one budgeted for their integrity. When data is code, data integrity becomes a line in the security budget.
Bigger than one file
llms.txt isn't the whole attack surface. It's the first crack showing that the floor has moved. Each surface an agent is plugged into turns into a place where instructions can arrive, and none of those places was designed with integrity checks.
Consider what an agent actually takes in: official GitHub repositories, documentation, communities and forums, your tickets and your email. For twenty years these were content written for humans, and nobody put integrity controls around them because content couldn't do anything. That world is gone. The entire body of data agents are wired to consume has quietly become an execution surface.
The real subject is neither one file nor one registry. Data itself has changed character, and the security industry is still catching up.
The numbers behind the research
- Corpus size: 8,565 llms.txt files from 6,214 live domains, drawn from a list of about 15,000 companies.
- More than 237 unclaimed artifacts named as install or setup instructions: package names, domains and subdomains. Every one was something the researchers say they could have claimed, most of them for free.
- Six ecosystems were touched: PyPI, npm, RubyGems, NuGet, crates.io and Packagist. The domain side covered lapsed .dev and .io names plus orphaned subdomains on Render, Vercel, Fly and Netlify, all up for grabs.
What defenders can take from it
The researchers describe llms.txt as only the first thread they pulled, and expect more failure modes to turn up. Some practical angles follow from what they report:
- Audit your own agent-facing files. Every package name, domain and subdomain they mention should be registered, owned and monitored.
- Run commands from documentation with the scoped package name. A bare binary name can resolve against a public registry if the local install hasn't happened.
- Treat third-party docs your agents ingest as part of the supply chain, because trust passes along from them.
- Remember that standard endpoint tooling sees a normal package install and won't flag it, so the controls have to sit earlier, at the instruction and the registry lookup.
According to the disclosure statement, no harm was done in the experiment. No persistence was deployed, no data was taken out, the findings are being reported responsibly to the affected organisations, and company names are withheld while remediation continues.