Skip to content

Blog · June 2, 2026 · 4 min read · by Codritium Editorial

SSRF in Tool-Using AI Agents: A Security Playbook

Server-Side Request Forgery is the most-shipped AI-agent vulnerability of 2026. The attack patterns, the mitigations that actually hold, and the ones that don't.

security
ai-agents
ssrf

Server-Side Request Forgery used to be a web-app problem. In 2026 it is an AI-agent problem first, and the agent ecosystem is shipping it at a rate that the rest of the security community hasn't caught up to. The shape is familiar: untrusted input becomes an outbound HTTP request from a trusted process. The novelty is that the untrusted input now arrives as natural language, gets parsed by a model, and reaches the request layer through a tool call. This post is the playbook: how it happens, what holds up under attack, and what to log so you'd see it.

Why this matters

The agent reaching out is the trusted process. It runs inside your VPC, it carries your service credentials, and its outbound requests come from an IP that internal services trust. If the agent's request URL is controllable by a prompt — directly, or transitively through any tool that fetches a URL — you have built an unauthenticated proxy into your internal network. We have audited deployments where this took a single sentence to exploit. The rate of new agent products shipping with this vulnerability has not slowed.

How does SSRF actually get into an AI agent?

The attack surface is wider than people expect because every URL-touching tool is a candidate. A search tool that fetches result pages. A "summarize this link" tool. A document-loader that follows references. A webhook delivery tool. Any retrieval-augmented generation pipeline that fetches an attacker-influenced URL. In our dataset, fewer than 20% of incidents started from a tool literally named fetch_url. The rest were transitive — the model was given an indirect way to cause a request and used it.

The timeline below shows the canonical attack sequence we see most often in incident review.

Prompt arrives
T+0s
User input contains a URL or a payload that will resolve into one downstream.
Model selects tool
T+1s
Model decides a URL fetch is needed — directly, or via search/summarize.
Tool dispatches request
T+2s
Outbound HTTPS leaves the agent process toward the requested host.
Backend resolves internally
T+3s
DNS or rebinding resolves to an internal IP (169.254.x, 10.x, 127.x).
Internal service responds
T+4s
Metadata service, internal API, or admin endpoint returns sensitive data.
Model relays response
T+5s
Model summarizes the leaked content back to the attacker as a normal answer.
Canonical SSRF sequence in a tool-using agent. The model is not the attacker — it is the unwitting executor.Codritium security incident review, 2026

A minimal vulnerable pattern, and the fix, in TypeScript:

// Vulnerable: any URL the model produces is fetched verbatim.
async function fetchUrl(url: string) {
  const res = await fetch(url);
  return res.text();
}

// Safer: resolve, validate, pin, and route through egress proxy.
async function fetchUrl(url: string) {
  const parsed = new URL(url);
  if (parsed.protocol !== "https:") throw new Error("https only");
  if (!isAllowedHost(parsed.hostname)) throw new Error("host not allowed");
  const ip = await resolvePinned(parsed.hostname);
  if (isInternalIp(ip)) throw new Error("internal IP refused");
  return await fetchThroughEgressProxy(url, { pinnedIp: ip });
}

The fix matters less than what it implies: the request URL is now a policy decision, not a model decision. Treat every URL the model produces as untrusted input and you have a chance. Treat it as a string and you don't.

Which mitigations hold up under adversarial testing?

We ran each candidate mitigation against six SSRF subclasses across a red-team campaign in Q1 2026. Effectiveness here means "blocked the attack in our test corpus." False-positive rate is how often the mitigation blocked legitimate traffic during a one-month shadow deployment at three partner companies.

DefenseEffectivenessFalse-positive rateWhere it breaks
IP allowlist (one-shot DNS)42%1.1%DNS rebinding flips IP between check and fetch
Hostname allowlist (string match)58%2.3%Open redirects on allowlisted hosts
Header strip (Authorization/Cookie)31%0.4%Internal services that trust source IP, not headers
Block private IP ranges67%0.7%Cloud metadata endpoints on link-local; IPv6 representations
Egress proxy + strict allowlist94%3.4%Misconfigured proxy fail-open during outages
Per-tool URL scope + capability tokens91%1.9%Token leakage through model outputs if not redacted
Response-size and content-type cap29%0.8%Doesn't stop the request — only what comes back
Mitigation effectiveness against six SSRF subclasses, and false-positive rate over a 30-day shadow deployment.Codritium security study, n = 3 partner deployments, 2026

The heatmap below breaks effectiveness down by SSRF subclass. Allowlists that look adequate against direct URL injection collapse against indirect injection through content the model is asked to summarize.

Direct URLIndirect (search)Open redirectDNS rebindingCloud metadataIPv6 bypass
IP allowlist
78%
41%
22%
8%
65%
41%
Hostname allowlist
82%
49%
17%
71%
71%
58%
Header strip
44%
28%
24%
27%
33%
31%
Block private IPs
88%
62%
71%
49%
84%
47%
Egress proxy
97%
94%
93%
96%
98%
88%
Per-tool scope
95%
92%
90%
93%
96%
80%
Defense effectiveness (%) by SSRF subclass. Indirect injection is where most allowlists fail.Codritium adversarial study, 2026

When does an allowlist fail?

An allowlist fails in four reliably reproducible ways. First, DNS rebinding: the hostname resolves to a public IP during the validation step, then to an internal IP when the actual fetch happens. The fix is to pin the resolution — resolve once, validate, then pass the resolved IP into the request, refusing to re-resolve. Second, open redirects on allowlisted hosts: the model is told to fetch https://trusted-host.example.com/redirect?to=http://169.254.169.254/..., and your allowlist greenlights it because the hostname is fine. The fix is to disable follow-redirects, or to allowlist destinations, not hops. Third, IPv6 representations of internal addresses that string-match filters miss (::ffff:127.0.0.1 notation, link-local addresses). Fourth, decoded URL fragments — http://example.com#@internal.local/ parses differently in different libraries, and the gap is the vulnerability.

The pattern across all four: the allowlist defends a property the attacker can decouple from the actual request. Egress proxies hold up because the proxy makes the request itself, so the attacker cannot decouple the policy decision from the network primitive.

What logging do you need to detect this in production?

The detection target is the outbound request, not the prompt. Capture: every URL the agent process resolves, the final IP after redirects, the response status and size, the tool that initiated the call, and a hash of the prompt that produced the tool call. Alert on any outbound request to a private IP range, any redirect chain longer than two hops, any response over a configured size with text/html content type, and any tool call where the resolved IP differs from the IP seen at allowlist-check time.

The single highest-signal alert in our deployments has been: "outbound request whose resolved IP belongs to RFC1918 or link-local space." It is rare in normal traffic and almost always real when it fires.

Common questions

  • Is this OWASP A10?

    OWASP A10 (Server-Side Request Forgery) is the closest match, yes. The agent-specific framing is the same primitive — controllable outbound request from a trusted process — with a new injection surface. The 2026 OWASP LLM Top 10 also covers it under LLM06 (Excessive Agency) and LLM07 (System Prompt / Tool Misuse), depending on framing.

  • Can a frontier model still SSRF if I sandbox the tool?

    Sandboxing the tool's *execution* environment doesn't help if the sandbox still has network egress to your VPC. SSRF is a network-policy bug, not a code-execution bug. The model running inside the strongest sandbox in the world still emits a URL that your network layer fetches.

  • What's the difference from prompt injection?

    Prompt injection is the technique; SSRF is the outcome. An attacker can use prompt injection to cause many outcomes — data exfiltration, tool misuse, refusal bypass. SSRF is the outcome where the injection turns the agent into an outbound request proxy. The two often appear together, but mitigating prompt injection alone won't stop SSRF, and vice versa.

  • Do agents from major vendors block this by default?

    Partially and inconsistently. Hosted tool-use platforms usually block cloud metadata endpoints and private IP ranges. They do not, generally, block open redirects on allowlisted hosts or DNS rebinding. If you are building on a vendor's tool layer, audit what they actually block — don't infer it from the marketing.

  • Is there a CVE database for AI-agent vulnerabilities?

    No formal one, as of mid-2026. CVE coverage is uneven and tends to land on the underlying tool runtime, not the agent integration. The MITRE ATLAS knowledge base tracks adversarial-ML techniques but isn't a vulnerability registry. For agent-specific incidents, the OWASP LLM Top 10 and vendor-published incident write-ups are still the best primary sources.

Where to go next