Enterprise & Security

Managed Agents: web_fetch only retrieves URLs that already appeared in the session

3 min read AI-generated

A URL from Claude's own output doesn't count. Neither does one from the system prompt, an attached document, or the output of bash or an MCP tool.

Featured image for "Managed Agents: web_fetch only retrieves URLs that already appeared in the session"

Anthropic shipped three changes to Claude Managed Agents on October 7, all pointing the same way: data shouldn’t be able to leave an agent over the network. The biggest one limits which URLs web_fetch is allowed to retrieve at all.

The URL has to have shown up in the session first

web_fetch now only fetches addresses that already appeared in the session — in the text of a user message, in a web_search result, or on a page web_fetch itself returned earlier.

What doesn’t count is the actual point. A URL that exists only in Claude’s own output isn’t enough. The agent’s system prompt isn’t enough. An attached document isn’t enough. And the output of a tool like bash, read or an MCP tool isn’t either. In all of those cases the call returns url_not_in_prior_context.

Anthropic names the reason plainly: reducing the risk of data exfiltration. The attack this closes is well known — a model reads an instruction buried in a document or a tool output, assembles a URL out of the data it’s currently looking at, and fetches it. The data then sits in the attacker’s server log. If the model isn’t allowed to invent the address, that stops working.

To let an agent reach a specific URL, you send it in the text of a user.message event.

allowed_hosts now covers the web tools too

The second change closes a gap between two settings that used to sit side by side. A cloud environment with limited networking applied its allowed_hosts only to the sandbox. Now they apply to web_search and web_fetch as well.

In practice: a web_fetch for a host that doesn’t match returns url_not_allowed. web_search omits results from such hosts. When allowed_hosts lists no hosts, neither tool returns anything. allow_package_managers and allow_mcp_servers add no hosts for the web tools — to open a host you put it in allowed_hosts, which also opens it to the sandbox. Unrestricted networking and self-hosted environments aren’t affected.

The third change turns a silent contradiction into an error: with limited networking, creating a session fails with a 400 when an enabled web tool’s allowed_domains holds an entry that isn’t within allowed_hosts. Same for a session update that adds one. And allowed_hosts matching is exact: docs.example.com is not within ["example.com"] unless the entry starts with *..

Existing agents can break on this

This isn’t a setting you turn on. It’s the new behavior.

An agent that reads a URL out of a database, a CSV or an MCP response and then fetches it stops working — and not with a network error, but with url_not_in_prior_context. The same goes for any agent whose worklist of URLs lives in the system prompt. If you run something like that, check it before the next run.

Anthropic closed this gap in the right place

Prompt injection has been the open problem with agents for years, and the usual countermeasure is a classifier: the model is supposed to recognize that an instruction inside a document isn’t an instruction. That works sometimes.

This change does something else. It takes away the capability the attack needs. Whether Claude spots the hidden instruction no longer matters — it can’t fetch the address, because the platform never saw it in the session. That’s the difference between a rule an attacker can talk his way around and one he can’t. There should be more of these.

Sources

AnthropicClaude PlatformManaged AgentsSecurityAgents