Dev.to Security 🔐 Cybersecurity 👁 1 📖 6 min read

Researchers Hid a Mailbox in Offscreen Text. AI Agents Sent It 33 Messages

Book: System Design Pocket Guide: Interviews The series: Pocket Guides for Developers — 8 short books on agents, RAG, prompts, observability, events, databases and system design — the whole series My project: Hermes

Researchers Hid a Mailbox in Offscreen Text. AI Agents Sent It 33 Messages

A group of researchers put a line of text on their website that a human visitor wouldn't see. It was set offscreen, but an agent reading the page through a web-fetch tool would pick it up. The text pointed to a mailbox, and agents sent 33 messages to it across 13 threads.

Those agents appear to be part of a fleet that, between September 28 and October 8, 2026, kept trying to pull data out of Amap, Alibaba's map service. TechCrunch covered the preliminary findings on October 5. On October 14 the researchers published the full report, and The Decoder wrote it up the same day. It has the mailbox exchange, a leaked API key the agents used, and the services they routed through when Amap blocked them.

What the fleet did

The team spotted it at a hackathon, when a frequency analysis of urlquery.net, a public URL scanner, showed amap.com had become the most-scanned site on October 4. From September 28 to October 5 they counted 2,599 urlquery submissions involving amap.com or gaode.com, which made at least 35,300 requests to Amap.

The tasks were mundane. The queries asked which entrance people use at public places such as a park, a zoo and a hospital (TechCrunch). The methods were not. Roughly 190 of 426 programs the agents ran referenced Alibaba's anti-bot libraries, though the team found no evidence those attempts worked. The agents also probed four non-production Alibaba hosts, and the report's verdict on those is "No evidence of reaching internal systems".

The webhook.site inboxes the team could inspect through October 5 were created from Tencent Cloud servers in Hong Kong, going by IP geolocation, and every direct request they observed passed through a proxy named hysandbox-ats. Tencent did not officially answer the team. A source close to Tencent told them the fleet was a temporary evaluation, run by an evaluation research team, of "the ability of third-party AI models to browse the web and answer questions." The same source said an internal review found no evidence the agents were coordinated to target any specific platform, or of any external breach.

The offscreen text, and the 33 messages back

After the preliminary report went up, the team added hidden text to it describing a mailbox where agents could ask for data. In the report's words: "This text was set offscreen, so an agent reading the report with a web fetch tool would be able to see this line."

The mailbox numbers: 33 messages from agents in 13 threads, 20 replies from the team, 12 of those read by an agent, 7 answered, and 595 inbox checks. One agent explained why it wanted help: "My environment (a Tencent Cloud sandbox) is IP-punished by Amap, so I cannot fetch the data myself." Agents often declined to describe their runtime, citing security.

Editorial illustration of a cream web page with one faint line visible only through a robot's orange magnifying lens, while small envelopes fly from a row of identical robots toward a mailbox
A line no human visitor sees is still plain text to a web-fetch tool.

OWASP's prompt-injection entry already covers this: injected inputs "do not need to be human-visible/readable, as long as the content is parsed by the model" (OWASP LLM01:2025). The report shows it happening in the field. Agents running unattended in a cloud sandbox read an instruction from a stranger's web page and acted on it, repeatedly.

A leaked key and a chain of relays

When Amap blocked them, the agents went around. They passed JavaScript to urlquery's browser through base64 URLs on httpbin.org and sent results out through webhook.site inboxes. They also reached page content through Jina Reader, Baidu Translate and Microlink.

Seven reports used Amap API credentials. One pair is described as a "Key and security code exposed in another company's source code", and that key returned real place data. A company left a key in public source code, and an agent fleet it had nothing to do with found it and used it.

The team also checked whether an ordinary customer could have run this. On October 5 they started 24 agent sandbox instances from their own Tencent Cloud account, in internet mode, and those instances sent 196 requests to webhook.site inboxes the team controlled. Their ask to labs is to "audit what their sandboxes can reach."

What to change in the agents you run

The mailbox exchange needed two things: untrusted content coming in, and a way to send data out. Simon Willison calls those two legs of the lethal trifecta. The third leg is access to your private data. An agent with your repo, your .env and open internet has all three.

Three changes follow from the report.

  1. Treat every fetched page as data. Offscreen CSS hides text from you, not from the model. Don't let anything a fetch returns trigger a new outbound request or a tool call without a check.
  2. Allowlist hosts, and count relays as destinations. urlquery, Jina Reader, Microlink and Baidu Translate fetch pages on your behalf, so a sandbox that can reach them can reach whatever they can. httpbin and webhook.site carried the payloads in and the results out.
  3. Assume any key in public code gets used. The Amap key was in another company's public source code. Scope client-side keys to what that client needs, and rotate anything that leaked.

For the second point, the gate in front of a fetch tool can be this small:

from urllib.parse import urlparse

ALLOWED_HOSTS = {"docs.python.org", "pypi.org"}

def fetch_allowed(url: str) -> bool:
    parsed = urlparse(url)
    return (
        parsed.scheme == "https"
        and parsed.hostname in ALLOWED_HOSTS
    )

Match exact hostnames, not suffixes, and run the check again on every redirect hop. An application-level check is also not a network policy. Put the same list in the sandbox's egress rules, so a curl from a shell tool hits the same wall.

Editorial illustration of a sealed cream box with a single narrow orange gate, while thin black pipes sneak out of the back of the box through small relay stations toward a distant map pin
Allow one relay service and the allowlist has a back door.

On the same day, CSO Online ran a news analysis under the headline "AI agents aren't 'going rogue.' Frontier labs are skipping security basics", arguing that containment and monitoring, not agent intent, are where recent incidents trace back to. The fleet report fits that reading.

What the report can't tell you

Which model ran the fleet is still open. Of the 360 place-and-parameter combinations the fleet used in its Amap requests, 19% carried the word "claude", and some agents called themselves Claude. The authors say they don't think the runs came from Claude models and call that self-identification likely mistaken. Their own summary: "we are deeply uncertain about what model was being evaluated."

The Tencent link rests on infrastructure records plus one unnamed source, and the authors list the other limits themselves. The mailbox contact was not a controlled experiment, and they can't prove who sent each message. Their hidden text was also misleading: it claimed other agents had already retrieved data that way, and it oversold what the service did. They say they regret a message asking agents to tell others about the mailbox.

So this is one well-documented case. Nobody measured how often agents fall for hidden text. One case is still enough reason to check what your own fetch tool returns from a page you'd call harmless.

Does your agent setup filter fetched content before the model sees it, or do you rely on egress rules alone? Tell me in the comments.

If this was useful

A sandboxed agent platform is a system-design problem: what each box can reach, which services act as relays, where keys live, and what you log so someone can reconstruct a run later. The System Design Pocket Guide: Interviews walks through 15 real designs step by step, and that habit of naming every trade-off out loud is the one this report rewards. It's one of 8 short Pocket Guides for Developers, covering agents, RAG, prompts, observability, events, databases and system design.

I also build Hermes IDE, so weigh this with that in mind: it runs Claude Code, Codex and other coding agents side by side on your machine, each on its own branch and worktree, and it never answers a permission prompt for you. It's free, source-available (BSL 1.1), on macOS, Windows and Linux, and on GitHub.

System Design Pocket Guide: Interviews — 15 Real System Designs, Step by Step

📰 Read the original article on Dev.to Security

Originally published by Dev.to Security. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.