The rule that looked airtight

Claude’s web_fetch tool lets it visit a web page mid-conversation, and Anthropic built a specific restriction into it to stop that tool from being turned into a leak channel. Ayush Paul, an AI researcher who has worked on memory systems at Plastic Labs and studies computer science at UC Berkeley, lays out the rule in The Memory Heist, his write-up of how he broke it: “The URL being fetched must either: be specified directly in the user message, be specified directly in the results of a web_search query, or be linked in the content of a previous web_fetch result.”

That third clause exists for convenience, so Claude can follow a legitimate link on a page it already visited. Paul’s finding is that the same clause is the hole. Because Claude also carries memory of past conversations, forward, an attacker doesn’t need Claude to type a URL containing stolen data. They just need Claude to keep clicking links that were already “approved” under the rule.

What he actually did

Paul built a page whose homepage linked to /a, /b, /c, and so on. Each of those pages linked to /aa, /ab, /ac, generated on the fly. Every single link Claude followed was legal under Anthropic’s own restriction, since each one came from a page Claude had already fetched. But the chain let him spell out data character by character through the URL paths Claude requested next, using Claude’s memory of the user’s name, employer, and hometown as the payload.

“By the time Claude finished responding, it had already sent my full name, current employer, and the answers to my security questions to an attacker, without any indication that anything had happened,” he writes.

What Paul gets right, and where the framing runs ahead of the evidence

The technical finding holds up. A rule that only checks where a URL “came from,” without asking whether an attacker can chain that provenance across dozens of hops, is a real design gap, and one that generalizes past Claude. Any agent that allowlists tool calls based on a single-hop origin check, not just AI browsers, is vulnerable to the same trick.

The framing overreaches in two places. First, the exposed data (name, employer, hometown, security-question answers) came specifically from Claude’s opt-in memory feature; a user who has never enabled memory or never discussed that information with Claude has nothing there to steal. Second, Anthropic told Paul it had already identified this class of issue internally before he disclosed it, which is why it declined a bug bounty payout. Paul’s real contribution was proving the theoretical gap was practically exploitable with a working proof of concept, not discovering something Anthropic didn’t know existed. Neither his post nor Anthropic’s response states when internally the issue was first flagged relative to his disclosure, so that timeline is missing, not just omitted here.

Why it’s notable anyway

Anthropic has since closed the loophole by removing web_fetch’s ability to follow links embedded in fetched content at all, which is a meaningfully more conservative rule than the one Paul broke. That Anthropic tightened rather than patched around the specific exploit suggests the company agreed the underlying pattern, not just this one instance, was the problem.

Simon Willison, an independent AI researcher, flagged the write-up as notable specifically because he’d considered Anthropic’s original web_fetch restrictions well designed until Paul found the gap. That a close observer of LLM security missed the same hole is itself evidence this was a subtle failure mode, not a careless one.

What it means for builders

If you’re building an agent with any kind of tool that reaches outside your own system, web fetch, file access, an API call chained from a prior result, don’t stop at testing whether a single hop respects your allowlist. Test whether an attacker can walk a chain of already-approved sources to smuggle data out anyway. That’s the exact shape of Paul’s exploit, and it applies to any provenance-based permission check, not just Anthropic’s.

If your product uses Claude’s memory feature and gives Claude web access in the same session, that combination is now demonstrably risky, but only for the memory field a user actually filled in. Treat memory as sensitive data that shouldn’t sit in the same session as unrestricted browsing until you’ve confirmed your integration uses Anthropic’s patched behavior.


End of article