CVE-2026-54729: dssrf SSRF Bypass via DNS NXDOMAIN on 1.1.1.1
A bug in the dssrf npm library lets an attacker reach internal services like localhost when the server uses the 1.1.1.1 DNS resolver, because the library skips a safety check whenever DNS returns no…

The problem
dssrf's is_url_safe() calls dns.resolve4() to resolve hostnames before checking whether the resulting IP is private or loopback. When the configured resolver is 1.1.1.1 (Cloudflare), it returns NXDOMAIN for localhost because that name has no public record.
With no address returned and no dns.lookup fallback, is_url_safe() sees an empty result set and incorrectly returns true, treating the URL as safe. An attacker can then supply http://localhost/admin (or any loopback/internal hostname) and the application will make the outbound request.
Proof of concept
A working proof-of-concept for CVE-2026-54729 in dssrf, with the exact payload below.
import { is_url_safe } from 'dssrf';
import dns from 'dns';
// Simulate a server whose DNS resolver is 1.1.1.1
dns.setServers(['1.1.1.1']);
const TARGET = 'http://localhost/admin';
const result = await is_url_safe(TARGET);
// On dssrf <= 1.0.4 with 1.1.1.1 as resolver:
// result === true -> SSRF bypass succeeded
console.log(result ? 'BYPASSED: dssrf treated localhost as SAFE' : 'Blocked');The root cause is a missing OS-resolver fallback. dns.resolve4('localhost') against 1.1.1.1 returns NXDOMAIN because that resolver does not answer for RFC-6761 special-use names. The library treated an empty address list as "no internal IP found" rather than as an error, so it returned safe.
The patch at commit 668c217 adds a dns.lookup call as a fallback whenever dns.resolve4 yields no addresses. dns.lookup always consults the OS resolver (which maps localhost to 127.0.0.1), so the loopback address is found, classified as private, and the URL is correctly rejected.
CWE-918.
The fix
Upgrade dssrf to version 1.0.5 or later. The fix is in commit 668c21792cd1252baf779a176aa652e2b4c0067d (PR #102). If you cannot upgrade immediately, force the Node.js process to use a system resolver (e.g., dns.setServers(['127.0.0.53'])) and add network-level egress controls so internal endpoints are not reachable from the application host regardless of library behavior.
Related research
- highCVE-2026-54722CVE-2026-54722: dssrf SSRF Bypass via Userinfo Stripping
- high · 7.4CVE-2026-54660CVE-2026-54660: swagger-typescript-api Authorization Token Exfiltration via Cross-Origin $ref
- high · 8.5Budibase REST Datasource SSRF via DNS Rebinding (undici dispatcher bypasses IP pin)
- high · 8.5Budibase: DNS Rebinding SSRF Bypass in OpenAPI Import and REST Query Execution