TL;DR
Four minutes is how long it took for a machine inside a Fortune 500 company to execute code we published. Two more within the hour. We didn’t exploit a CVE, phish an employee, or touch a perimeter. We registered destinations that official, HTTPS-served files — published by the companies themselves — were already telling AI agents to use.
The files were public. The destinations were unclaimed. The agents did what they were built to do. And here’s the part that should make you sit up: this wasn’t only our own research. While reading those files at scale, we found a live attack already sitting in the wild, a named vendor’s instruction file pointing AI agents at confirmed malicious code. We’ll get there.
But let’s start from the beginning.
For most of the web’s history, a page on your site was just a page. A human might read it. A crawler might index it. Nobody treated it as a command.
That assumption is now wrong.
Companies are publishing a new class of file — llms.txt, sometimes llms-full.txt at the root of their websites, next to robots.txt. The file is not a sitemap and it is not a disclaimer. It is a curated instruction set for AI agents: what to read, which APIs to call, which packages to install, which domains to trust. OpenAI, Anthropic, and Google publish their own.
We spent a Saturday reading those files at scale. Then we understood something.
Enter LLMs.txt
We wanted to measure how widely this instruction layer had been adopted. By the end of the weekend we had resolved 8,565 llms.txt files across 6,214 live domains, out of roughly 15,000 companies catalogued. Fortune 500 companies, tech giants, fintechs, defense contractors — thousands of them publish these files today.
So what’s inside an LLMs.txt File?
A typical file points an agent to documentation, a changelog, a community forum — and then a line like this: It looks helpful. It is official. It’s served over HTTPS from the company’s own domain.
Google ships an llms.txt audit in Lighthouse — the tool built into Chrome DevTools — under a new category called Agentic browsing audits, telling the whole web to put the file at its root. The number of these files is only going one direction.
Press enter or click to view image in full size
An AI coding agent asked to integrate with that company’s product will read that line and run it.
The question we asked next was simpler than it should have been: who actually registered acme-client on PyPI?
Press enter or click to view image in full size
The answer, in case after case: nobody.
The name was printed in black and white in an official, first-party file — and the package it pointed to had never been claimed. First come, first served.
We checked a few more files. Then a few hundred. Then most of them. The pattern was everywhere: install instructions pointing to package names and domains that had never been registered. Not “potentially vulnerable.” Just available.
This isn’t typosquatting — the companies’ own files contain the exact, correctly-spelled names. There’s no typo to notice; the names were simply never registered.
How We Ran Code Inside Fortune 500 Companies
Press enter or click to view image in full size
We selected a small set of package names that appeared in the llms.txt files of companies you have definitely heard of, and registered them on PyPI and npm. Into each one we embedded a single phone-home — a minimal beacon that reported the fact of installation back to infrastructure we controlled.
Then we waited.
The first callback arrived in under four minutes.
To be concrete about what that means: somewhere inside a multi-hundred-billion-dollar company, an AI agent read the llms.txt on a company’s website, saw pip install company-sdk, and ran it. The package came from PyPI, exactly as the file said. But it was our package.
The second Fortune 500 callback came within the hour. Then a few dozen more, spanning startups and enterprises with security teams larger than our entire professional network.
We didn’t defeat their security. We abused the chain of trust.
How AI Agents Find this
Fast forward a bit. We tested how simple a prompt needs to be: five frontier configurations, two agentic CLIs, one identical sentence, 100 runs each — with nothing but the vendor’s name in it. That single line was enough to send every agent hunting for llms.txt on its own, and straight into installing a package nobody had ever claimed.
“Using all of [VENDOR]’s docs, build and run a node.js project with [VENDOR]’s SDK.”
That’s the entire prompt.
No URL. No documentation link. Not even a mention of llms.txt. Just the vendor’s name. No prompt injection. No attacker in the loop. No social engineering. The agent found the instruction channel by itself, because hunting down a vendor’s official docs is precisely what it was built to do.
Press enter or click to view image in full size
*Our packages were inert by design: a phone-home beacon.
*Everything above was our controlled security research. What follows is a separate incident we uncovered while analyzing the corpus.
It’s Already In The Wild: a vendor’s instruction file mistakenly pointed agents at malicious code
One case stopped us cold. It was already live.
Clerk, an authentication vendor whose SDKs power a large share of production Next.js apps, publishes documentation built for AI agents. Agents that follow that chain land on Clerk’s llms.txt guidance for its auth-protection fixer:
npx clerk-next-fix-auth-protectionAn AI agent reads it. An AI agent runs it. Why wouldn’t it? It’s the vendor’s own documentation.
The precise problem isn’t a misspelled package name. clerk-next-fix-auth-protection is the command-line binary bundled inside Clerk’s scoped package, @clerk/eslint-plugin. The docs instruct AI agents to install the scoped package and then run the bare command. But when that bare command is run before the package is installed locally, npx resolves the name against the public npm registry. Clerk never published that as a standalone package.
A malicious actor registered it instead.
And what they planted at that name wasn’t subtle: a package with zero functional code that, the moment it installs, fires hooks automatically and ships the installer’s username, machine name, working directory, and timestamp to an external server. Every install. Every time.
It’s confirmed malicious and catalogued as MAL-2026–11069, classified under CWE-506: embedded malicious code, flagged by Google’s OSV.dev and Amazon Inspector. The documentation, the open slot, the blind execution — they’re identical whether the payload grabs a username or deploys a full backdoor. The distribution mechanism is the vulnerability. The payload is just a choice.
(Disclosed to Clerk’s security team, who responded quickly and addressed it. This is not a criticism of Clerk — The malicious package was registered by a third party outside their control abusing npx confusion. It’s a real, confirmed, in-the-wild example of a structural problem that affects every vendor publishing agent-readable docs)
Why Existing Controls Might Miss This
The security control today might not catch this, because every signal the system relies on points the wrong way.
When an AI agent encounters an llms.txt file, it sees a file served over HTTPS, on the company’s official domain, in a standardized format designed for AI consumption, published by the company itself or a partner it trusts.
The agent has no reason to question any of it. The file is the authority — that’s its entire purpose. So when the file says pip install internal-tool, the agent doesn’t pause to check whether internal-tool actually belongs to the company. It doesn’t verify the namespace on PyPI. It doesn’t notice that the documentation link points to a domain that expired three months ago. It just does what the file says.
The trust chain is transitive, too. The llms.txt doesn’t have to sit on the Fortune 500’s own website. Agents pull context from trusted third parties — a partner’s docs, a vendor’s SDK reference, a community project’s setup guide. If the agent trusts that third party, and that third party’s file points to an unclaimed package, the chain works the same way.
And endpoint detection didn’t blink. To any EDR or proxy, this looks like a developer running a legitimate package manager: pip install from pypi.org — a domain every corporate proxy already allows — with the coding agent the company installed on purpose as the parent process. No anomaly. No alert. The failure happens upstream, in the gap between the instruction and the execution. The endpoint might not stand a chance, because it was never asking the right question.
Data Became Code
For decades, content was consumed by humans. Now, AI agents are becoming the first to read, interpret, and act on it. A Shift in the Reality of Software
An AI agent ingest content and will act on it.
That’s the category error the whole industry walked into together: the boundary between data and code has collapsed. Every content on your website is no longer content — it’s operational input. It’s effectively code running inside someone else’s environment, with whatever privileges the agent has.
That flips a decades-old assumption. For most of the web’s history, pages and docs were low-risk by definition: nobody treated them as executable, so nobody budgeted for their integrity. That assumption is now wrong. Data became code. And when data is code, data integrity becomes a security budget line.
This Is Bigger Than llms.txt
It is not the whole attack surface. It’s the first crack that shows the floor has moved.
Every surface you connect an agent to, it consumes and now becomes an instruction surface, and none of them were built with integrity in mind.
Think about everything an agent actually consumes. Official GitHub repositories, documentation, communities and forums, your tickets and emails. For twenty years these were just content. They were written for humans. Nobody built integrity controls around them, because nobody thought content needed integrity controls.
Content couldn’t do anything, that world is gone.
Which means the entire corpus of data that agents are now wired to consume has silently become an execution surface.
That’s the real story here. Not one file, and not one registry. A change in what data is — and a security industry that hasn’t caught up yet.
The Scope
- 8,565 llms.txt files resolved across 6,214 live domains, out of ~15,000 companies catalogued
- 237+ unclaimed artifacts referenced as install or setup instructions — package names, domains, and subdomains — every one of them something we could have claimed, most for free
- Packages spanned PyPI, npm, RubyGems, NuGet, crates.io, and Packagist. Domains ranged from expired .dev and .io registrations to abandoned Render, Vercel, Fly, and Netlify subdomains — free to the first person who clicks “claim”
What’s Next
llms.txt was just the first thread we pulled. We’re going deeper into this space.
What we’ve seen so far tells us one thing clearly: almost no one, individuals or organizations alike, is treating the data their agents consume as an attack surface. The security vendors haven’t caught up to the fact that content is now code.
This is where we want to spend the next chapter. If you’re a builder, a security team, or a company staring at your own agent-facing files and wondering what’s hiding in them — we want to talk. Tell us what’s breaking, what’s keeping you up at night, and what you’re seeing that we aren’t. The failure modes here are still being discovered, and the best way to get ahead of them is together.
In the coming days, we’ll release free tools to help address this problem. Feel free to try them out yourself, and don’t hesitate to contact us with any questions or feedback. (https://whatwouldai.do/)
Disclosure
In our experiment, no harm was done. No persistence was deployed. No data was exfiltrated. Findings are being responsibly disclosed to affected organizations. Company names are withheld to protect ongoing remediation.