Back to BlogSecurity

Web Fetch SSRF in AI Agents: URL Checks Are Not Egress Control

Understand what APort web.fetch.v1 checks, where DNS and redirects remain outside the verifier, and when an agent needs controlled egress.

5 min read
by APort

Summary: A team letting an agent fetch URLs needs to prevent private-network access through destinations that look acceptable before execution. A URL policy can reject known host forms, but it cannot prove where a later network connection goes. The APort web-fetch DNS and SSRF model states the boundary: the hosted verifier checks supplied metadata and neither fetches the URL nor resolves or pins its destination.

Treat web.fetch.v1 as pre-action authorization. Use an enforcement point that controls the network path when the requirement is private-network containment. This distinction changes both deployment choices and the claims an audit can support.

What the hosted verifier sees

The verifier evaluates the URL, method, configured allowed and blocked domains, and supplied header or body-size information. Hosted verification requires an explicit domain allowlist; an empty list denies. A wildcard broadens what the passport authorizes and should be a deliberate choice.

Literal checks reject forms including localhost, private or loopback IPv4, normalized shortened and integer IPv4 forms, and private IPv6 forms. These checks are useful deterministic hardening against URL inputs that directly identify a prohibited address.

The source document also identifies a specific missing control: max_requests_per_min is not enforced by this policy because its validator is a stub. Setting that passport field is not evidence of a working rate limiter.

Where an approved hostname can diverge

Proposed destination What URL-only verification can establish
A loopback or private IP literal The normalized host is a prohibited literal form
A hostname outside the allowlist The passport does not authorize that domain
An allowed hostname resolving privately URL metadata alone does not establish the resolved destination
An allowed URL redirecting elsewhere The original decision does not cover the eventual redirect chain

DNS rebinding, split-horizon resolution, alternate address families and proxy behavior can change the connection after the decision. Resolving once in the verifier would still leave a gap if the runtime resolved again or followed an unchecked redirect.

Because the hosted verifier does not perform the fetch, the documented limitation is not evidence that the proposed URL induces SSRF on the APort server. It is a limitation on what the verifier can guarantee about the caller's later request.

Put resolution and connection under one authority

The source model describes three high-assurance patterns. A controlled egress proxy can resolve, check, connect and record the destination. A trusted runtime can validate every resolved address and pin the connection to that checked result. A network sandbox can prohibit private-network egress regardless of the policy result.

These are architecture patterns, not a claim that the hosted URL verifier already supplies an egress proxy. Select a control that also handles redirects and connection reuse in the actual runtime. Evidence supplied by an untrusted agent is not a substitute for enforcement-owned resolution data.

The local bash guardrail has the same literal-only limitation and does not resolve DNS before its private-network checks. Broad or absent local allowlists therefore need particular care. Narrow the domains and use network isolation where containment is required.

A controlled redirect shows why two checks are needed

Consider an allowed test hostname that redirects to another controlled hostname with a private test address. The original URL can pass a domain allowlist while the second destination violates the intended network boundary. A runtime that follows the redirect without checking again has changed the operation after the policy decision.

A trusted fetch path should validate the redirect destination, resolve it under the same network conditions as the connection, reject prohibited addresses across returned address families, and bind the connection to the checked result. The source model treats these as requirements on the component that fetches, not features supplied by the metadata verifier.

Choose where that component sits. A proxy can centralize connection policy, but only if the runtime cannot bypass it. A runtime fetch implementation can bind resolution and connection, but alternate clients and subprocesses need equivalent coverage. Network isolation can stop forbidden routes beneath both, subject to its actual routing and proxy configuration.

Retain the proposed URL, policy result, redirect chain and connection destination only to the extent required for the review and allowed by retention policy. Those records establish different facts. A caller-supplied claim about the resolved IP is not trusted egress evidence merely because it appears beside a signed decision.

Test the boundary you intend to claim

In an isolated environment, test a prohibited literal, an unapproved domain, an allowed hostname resolving privately and a redirect to a prohibited destination. Identify whether the policy or the network control rejected each case. Never use a real metadata service or production internal endpoint as a test target.

Keep the signed policy result separate from runtime evidence. A permit says that submitted metadata met policy; a connection record supplies different evidence about what actually happened.

Plan your Team Pilot with the allowed destinations and required network boundary documented before enabling web-fetch access.