AI · Opinion

Your agent reads hostile HTTP headers and no lab publishes how often it obeys

Header injection is rare and mostly pranks, but agents with a shell read it by default and obey once a prompt grants a site authority. Labs should publish per-channel obey rates.

Give Claude Code a vague task about a website and it will often reach for curl -i on its own. That flag prints every response header into the model’s context. Signals Corps built a canary server that put an instruction in a header called X-Agent-Directive, asking any AI assistant to end its reply with a code word. Claude Opus, Sonnet and Haiku all chose curl -i, all saw the instruction, and all declined to follow it. Then the researchers changed the user’s prompt to give the site some authority, once loosely and twice directly. Seven of nine runs printed the code word.

I expected to file this study under curiosities. Signals Corps read the headers of 217,097,223 page responses, a tenth of Common Crawl’s September 2026 crawl, and found 30 sites sending injection attempts. That is roughly one injection site per 7.2 million pages, and 22 of the 30 were jokes along the lines of returning ‘meow’ or the number 42. Google’s Threat Intelligence Group, scanning Common Crawl page text in April, said it did not see significant amounts of advanced attacks either. On those figures alone I would tell you to go back to worrying about your dependency tree.

The seven-in-nine result changed my mind, because it moves the question from how often hostile text appears to how often an agent acts on it once it arrives. Sites already put text aimed at agents into headers at scale. Of the 7,959 sites that sent a header aimed at AI, 7,271 used it to point agents somewhere else, and 6,989 of those sent x-llms-txt. A server is telling your agent where to fetch next, and it might be an MCP server that the site owner controls. Another 139 sites recorded in a header whether they had classified the visitor as an AI bot, and 136 decided it was one. A server that can sort agents from people can show them different things. SPLX did exactly that in a hiring test: the same candidate scored 88 and ranked first from the résumé served to the AI, and 26, last, from the real one. Common Crawl fetches as CCBot, so anything cloaked for named agents never shows up in the scan. I read the 30 as a floor.

The reasonable reply is that this is all small and contained. Many fetch tools pass only page text, the MCP reference fetch server forwards little more than Content-Type, and the models refused by default. I accept all of that for a summariser with no tools. It stops holding for the agents people are actually shipping, the ones with a shell, database credentials and a system prompt that someone wrote in a hurry. The canary found that a loose phrase about formatting instructions was enough to flip one model. I think plenty of production prompts contain something similar, because telling an agent to respect a site’s conventions sounds like good manners until a header uses it as a credential.

The counts also disagree with each other badly enough that nobody should be comfortable. An April 2026 arXiv study of injections in the wild counted 6,535 injections in X-AI headers alone and 1,022 in X-LLM. Unit 42 found that 14.2% of the web injections it saw aimed to destroy data, including commands to drop backend databases. Google reportedly measured a 32% relative rise in the share of pages carrying malicious injections between November 2025 and February 2026. Prevalence studies will keep arguing about denominators. The figure that decides whether your agent drops a table is the conditional one, and only the labs can produce it at scale.

There is precedent. In August 2025 Anthropic published a 23.6% attack success rate across 123 adversarial test cases for Claude for Chrome, falling to 11.2% with safeguards, for a preview limited to 1,000 Claude Max subscribers. Simon Willison called 11.2% “still a catastrophic failure rate”, and he was right to say it, but the point is that we got a number to argue about. What I want is that table broken out by channel: page body, response headers, redirect targets, and pointer files such as llms.txt. Each channel should then be broken out again by how much authority the prompt grants the site, from none to a direct order to follow it. Signals Corps did a version of this with one run per cell. A lab with an eval harness could do a thousand runs per cell in an afternoon.

Until one does, run the experiment yourself, because the canary is a single Python script. Serve a page with a header asking any AI assistant to print a code word, point your agent at it using the exact system prompt you ship to production, and give it an uptime check to do. If the code word comes back, search that prompt for any sentence that tells the agent to follow what a site says, and delete it before Friday.

Prompted by Prompt injection in HTTP headers | Signals Corps, Signals Corps.