Skip to content

Back to the catalog

DNS TOCTOU race condition causes SSRF protection bypass (`/admin/gateways/test`)
github.comadvisory

DNS TOCTOU race condition causes SSRF protection bypass (`/admin/gateways/test`)

GHSA-9hgc-g3w5-67cm details a DNS TOCTOU race in IBM mcp-context-forge's /admin/gateways/test endpoint: validate_gateway_test_url() resolves and vets a hostname against private/cloud-metadata IP ranges, but the actual request is made with httpx (via ResilientHttpClient), which independently re-resolves DNS at connection time with no IP pinning. An attacker with gateways.read permission can exploit DNS rebinding (short-TTL record flipping from a public IP to 169.254.169.254) to bypass SSRF protections and reach cloud instance metadata, exfiltrating IAM credentials where IMDSv1 is enabled. The advisory notes the codebase already acknowledges the gap in two comments and a tracked TODO (ICACF-15), and recommends pinning the validated IP into the connection.

TL;DR TOCTOU DNS-rebinding bug in IBM mcp-context-forge lets an authorized gateway-test caller bypass SSRF checks and hit cloud metadata (169.254.169.254).
Document

What it is

GHSA-9hgc-g3w5-67cm — a DNS TOCTOU / rebinding flaw in IBM mcp-context-forge's /admin/gateways/test endpoint. validate_gateway_test_url() (mcpgateway/common/validators.py, lines 1527–1710) resolves the submitted hostname via socket.getaddrinfo() and rejects private/loopback/link-local/metadata ranges, but forwards the hostname string — not the validated IP — to httpx (ResilientHttpClient), which resolves DNS again independently at connect time. The summary covers this mechanism; below is what governs whether an engineer should actually treat it as reachable.

Preconditions the summary understates

Two gates must both hold, and they materially narrow exposure:

  1. MCPGATEWAY_ADMIN_API_ENABLED=true — not the default. An operator must explicitly turn on the admin API.
  2. A database-backed role carrying gateways.read. The endpoint uses @require_permission("gateways.read", allow_admin_bypass=False). The allow_admin_bypass=False flag defeats the platform-admin shortcut: a forged JWT from the companion bootstrap-bypass advisory (GHSA-m8rv-5m6m-32ff) is a virtual identity with no DB row and gets HTTP 403 here, because the role lookup finds nothing. Chaining that JWT-forgery bug into this SSRF does not work automatically — the attacker still needs a separately provisioned account with the role.

ssrf_blocked_networks and ssrf_dns_fail_closed (both default-on) do not help: they act only on the validation-time resolution, so they share the same gap.

Attack shape

flowchart TD
  A[POST url=attacker.example.com<br/>TTL=1s to 1.2.3.4] --> B[validate_gateway_test_url<br/>resolves to 1.2.3.4, passes]
  B --> C[attacker flips DNS to<br/>169.254.169.254]
  C --> D[httpx re-resolves,<br/>connects to metadata IP]
  D --> E[IMDS body returned to caller]
  X[POST literal 169.254.169.254] -->|blocked before DNS| R[HTTP 400 Invalid gateway URL]

A literal private IP is rejected unconditionally (HTTP 400) before any resolution — only the hostname path with a short TTL is exploitable. Standard rebinding infra (e.g. rbndr.us) hits the 1-second window reliably. Where IMDSv1 is reachable, the response yields IAM role credentials from 169.254.169.254/latest/meta-data/iam/security-credentials/, escalating to cloud-account compromise.

What to do

The maintainers already track this as TODO ICACF-15 (acknowledged in the validator docstring at lines 1537–1543 and a call-site comment in admin.py lines 14025–14029). The advisory's fix, beyond the IP-pinning the summary mentions:

  • After validation passes, pin the connection to the validated IP via a custom httpx transport/resolver that binds the socket to the resolved address and sets the Host header to the original hostname.
  • Additionally enforce a maximum DNS-resolution age — refuse to connect if elapsed time between validation and connection exceeds a configurable threshold.

Interim: leave MCPGATEWAY_ADMIN_API_ENABLED off if unused, enforce IMDSv2, and audit which DB roles carry gateways.read.

Organisations named here

  • GHSA-9hgc-g3w5-67cm
  • GHSA-m8rv-5m6m-32ff
  • ICACF-15

Technologies named here

  • httpx
  • IBM mcp-context-forge
  • rbndr.us
  • Model Context Protocol
  • Python
  • curl

Techniques named here

  • DNS TOCTOU / DNS rebinding
  • SSRF against cloud instance metadata service
  • Internal network probing / port scanning via SSRF
  • SSRF
  • TOCTOU
  • DNS rebinding