CVE-2026-77972 Overview
CVE-2026-77972 is a Time-of-check Time-of-use (TOCTOU) race condition [CWE-367] in the Slab safeurl library for Elixir. The library validates URLs to prevent Server-Side Request Forgery (SSRF), but the validation logic returns only a verdict rather than the resolved address it approved. The bundled HTTP clients then resolve the hostname a second time when issuing the request, opening a DNS rebinding window. An attacker controlling authoritative DNS for a hostname can return a permitted address on the first lookup and an internal address on the second, bypassing the SSRF allowlist. The flaw affects safeurl versions from 0.1.0 onward.
Critical Impact
Attackers can reach internal network destinations that the library's SSRF protections were designed to block, exposing metadata services, internal APIs, and other private resources.
Affected Products
- Slab safeurl (Elixir library), versions 0.1.0 and later
- Applications using safeurl-elixir for SSRF mitigation
- HTTP clients bundled with safeurl that perform their own DNS resolution
Discovery Timeline
- 2026-09-15 - CVE-2026-77972 published to NVD
- 2026-09-16 - Last updated in NVD database
Technical Details for CVE-2026-77972
Vulnerability Analysis
The safeurl library is designed to mitigate SSRF by blocking requests to private or reserved IP ranges. The validation function parses a URL, resolves the hostname, and checks whether the resulting address falls inside an allowlist or blocklist. The function returns only an accept/reject verdict, discarding the address it validated.
When the caller then issues the HTTP request, the HTTP client receives the original hostname string and performs a fresh DNS lookup. This second lookup is not bound to the address that passed validation. If the DNS answer changes between the two lookups, the request reaches a destination that the library never approved.
The condition also triggers benignly when a hostname legitimately resolves to multiple addresses, such as records with short time-to-live values or round-robin rotation. In both cases, the SSRF control fails open.
Root Cause
The root cause is that validation and use are decoupled across two independent DNS resolutions. The verdict-only return signature prevents the caller from pinning the request to the exact address that was checked, which is the defining pattern of a TOCTOU flaw [CWE-367].
Attack Vector
An attacker registers or controls a domain and configures its authoritative DNS server to return different answers to sequential queries. The attacker submits a URL using that hostname to an application that relies on safeurl for SSRF protection.
The first resolution during validation returns a public IP that passes the allowlist. The second resolution, performed by the HTTP client, returns an internal address such as 127.0.0.1, 169.254.169.254 (cloud metadata service), or an RFC 1918 range. The application then issues the request to the internal target and may return response data to the attacker.
// Vulnerable pattern from safeurl-elixir (pre-patch)
// Source: https://github.com/slab/safeurl-elixir/commit/feabbd0a13f83028ab24b71710526e9da9841f70
defmodule SafeURL do
@moduledoc """
A library for mitigating Server Side Request Forgery vulnerabilities in Elixir.
Private/reserved IP addresses are blacklisted by default...
iex(10)> SafeURL.get("https://10.0.0.1/ssrf.txt")
{:error, :restricted}
iex(10)> SafeURL.get("https://google.com/")
{:ok, %HTTPoison.Response{...}}
"""
# Validation returns only a verdict; the HTTP client resolves the hostname
# a second time, allowing a DNS rebinding attacker to swap the address.
end
Source: GitHub commit for safeurl-elixir
Detection Methods for CVE-2026-77972
Indicators of Compromise
- Outbound HTTP requests from application servers to RFC 1918 addresses, 127.0.0.0/8, or link-local ranges such as 169.254.169.254.
- DNS query logs showing repeated lookups of the same hostname within short intervals returning different address families.
- Application logs showing user-supplied URLs whose hostnames resolve to both public and private addresses.
Detection Strategies
- Correlate DNS resolver logs with outbound socket connections to identify hostnames that resolved to attacker-controlled public IPs followed by internal IPs.
- Alert on any request originating from an application process to cloud instance metadata endpoints such as 169.254.169.254 or metadata.google.internal.
- Baseline the destination IP ranges each application service normally contacts and flag deviations.
Monitoring Recommendations
- Capture and retain DNS query and response telemetry from application hosts for correlation with egress traffic.
- Monitor egress firewall logs for denied and allowed connections to internal CIDR ranges from user-facing services.
- Ingest application, DNS, and network flow logs into a central data lake to enable cross-source hunting for DNS rebinding patterns.
How to Mitigate CVE-2026-77972
Immediate Actions Required
- Upgrade safeurl to a patched release once available from the Slab safeurl-elixir repository and review the CNA advisory.
- Inventory all Elixir services that depend on safeurl version 0.1.0 or later using mix deps and prioritize internet-exposed applications.
- Block outbound access from application servers to internal ranges and cloud metadata endpoints at the network layer as a compensating control.
Patch Information
Refer to the upstream repository at slab/safeurl-elixir and the OSV entry EEF-CVE-2026-77972 for fixed version information. The remediation pattern requires validation to return the resolved address and the HTTP request to connect directly to that address rather than re-resolving the hostname.
Workarounds
- Enforce egress filtering that denies traffic from application hosts to 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 127.0.0.0/8, and 169.254.0.0/16.
- Route outbound requests through an HTTP proxy that performs its own SSRF validation and pins connections to a single resolved address.
- Disable or restrict the IMDSv1 metadata service on cloud instances and require IMDSv2 with hop-limit restrictions.
# Example iptables egress rules to block internal destinations from an app user
iptables -A OUTPUT -m owner --uid-owner appuser -d 169.254.169.254 -j REJECT
iptables -A OUTPUT -m owner --uid-owner appuser -d 10.0.0.0/8 -j REJECT
iptables -A OUTPUT -m owner --uid-owner appuser -d 172.16.0.0/12 -j REJECT
iptables -A OUTPUT -m owner --uid-owner appuser -d 192.168.0.0/16 -j REJECT
iptables -A OUTPUT -m owner --uid-owner appuser -d 127.0.0.0/8 -j REJECT
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

