system: OPERATIONAL
← back to all hacks
AGENTS MEDIUM NEW

SSRF fixes that don't hold: DNS rebinding and bypassed URL guards in agents

Two July 2026 disclosures show how SSRF patches in agent frameworks fail — one re-resolves a hostname after validating it, the other never routes some fetch paths through the guard.

2026-07-22 // 7 min affects: mcp-atlassian, langflow, mcp-servers, ai-agents, rag

What is this?

Two disclosures published in July 2026 land on the same uncomfortable point: shipping an SSRF fix in an agent framework is not the same as being safe from SSRF. A server-side request forgery (SSRF) flaw lets an attacker make a server fetch a URL of their choosing — typically to reach internal services or a cloud metadata endpoint such as 169.254.169.254, which can return IAM credentials.

On 2026-07-10, a GitHub advisory for the mcp-atlassian MCP server described a way to defeat an already-patched SSRF guard using DNS rebinding. Separately, a July 2026 advisory for Langflow (the visual builder for LLM pipelines) showed that certain legacy fetch components made requests without going through the SSRF protection that had been added in an earlier release. Different products, different mechanisms, one lesson: the boundary that decides whether a fetch is allowed has to be the same boundary that actually opens the socket.

How it works

The two cases fail in complementary ways.

In mcp-atlassian, the fix added a validate_url_for_ssrf check. When a request carried an attacker-influenced host in an X-Atlassian-*-Url header, the guard resolved that hostname once, confirmed every returned address was a public (global) IP, and returned a pass/fail verdict. The problem is what it returned: a verdict, not the IP it had just approved. The code that actually performs the outbound request was then built from the raw hostname and re-resolved it at connect time. That gap between the check and the use is a classic time-of-check to time-of-use (TOCTOU) race (CWE-367). An attacker who controls the authoritative DNS for their domain can answer the first lookup with a public IP (guard passes) and the second lookup with an internal address (the socket connects there). The result is SSRF (CWE-918) on the patched build.

# TOCTOU with DNS rebinding — why "validate then fetch" is not enough

  t0  guard: resolve(host) -> 93.184.216.34  (public)  -> PASS, verdict discarded
  t1  fetch: resolve(host) -> 169.254.169.254 (metadata) -> socket connects HERE

  The check and the connection resolved the SAME name to DIFFERENT IPs.

Langflow’s issue is simpler and, in a way, more common: the guard was there, but not every path went through it. SSRF protections introduced in an earlier version did not cover some legacy fetch components (an RSS reader and a metasearch connector), which still issued requests to a user-supplied URL directly. Because those components can run in agentic mode, the URL does not even need to come from a human operator — it can arrive through indirect prompt injection in the content the agent is processing. No working rebinding server or payload is reproduced here; the point is structural, not a recipe.

Why it matters

Both bugs live in software whose whole job is to let a language model reach the outside world: an MCP server that talks to Atlassian, a pipeline builder that fetches feeds and search results. In that setting the “user” supplying a URL is frequently the model, and the model’s inputs can be shaped by a ticket, a web page, or a document it just read. An SSRF primitive here is not an abstract network bug — it is a direct line from untrusted agent input to cloud-metadata credentials and internal services, which maps to the tool-and-integration risks in the OWASP LLM Top 10.

The deeper reason these matter is that both are incomplete-fix stories. A CVE was filed, a patch shipped, dashboards went green — and the protection still did not hold, because validation and connection disagreed about which address was being contacted, or because a second code path never consulted the validator at all. That is exactly the kind of regression that automated “is it patched?” checks miss.

Defenses

The durable mitigations for this class are about making the validated decision authoritative all the way to the socket:

  1. Pin the validated IP to the connection. Have the SSRF check return the specific address it approved, then force the outbound request to connect to that IP (custom resolver, cached getaddrinfo, or an adapter that overrides resolution) while preserving the original Host header. This closes the DNS-rebinding window because there is no second resolution to poison.
  2. One choke point for all egress. Route every outbound fetch — including legacy, optional, and “convenience” components — through the same validated HTTP client. Bugs like Langflow’s happen when a side path forgets the guard exists.
  3. Block the sensitive targets at connect time, not just at parse time. Deny link-local, loopback, and private ranges (and the metadata IP) when the socket is opened, so a late-resolving name cannot slip past a name-based allowlist.
  4. Treat agent-supplied URLs as attacker-controlled. Assume any URL a tool receives may have been steered by content the model ingested; validate at the tool boundary as if it came from an anonymous internet user.
  5. Least privilege on the runtime. Prefer IMDSv2 (or the cloud equivalent) and scope instance roles tightly, so that even a successful metadata fetch yields little.

Status

ItemReferenceDateNotes
mcp-atlassian SSRF (header)CVE-2026-27826 / GHSA-7r34-79r5-rcc92026Original X-Atlassian-*-Url SSRF; fix added validate_url_for_ssrf
mcp-atlassian rebinding bypassGHSA-489g-7rxv-6c8q2026-07-10Incomplete fix; TOCTOU (CWE-367) + SSRF (CWE-918); verdict not IP-pinned; patched in 0.22.0
Langflow SSRFCVE-2026-105462026-07Legacy fetch components bypass SSRF protection added in 1.9.3; reachable via agentic tool mode
ClassOWASP LLM Top 102025Insecure tool/integration design, excessive agency

All details above come from the vendor advisories and public CVE records; both issues are disclosed. The takeaway generalises beyond these two products: any agent framework that fetches URLs should assume that validating a hostname and then re-resolving it — or leaving a second fetch path unguarded — reopens the exact hole the patch was meant to close.

Sources