FlawOpen

flawopen.com/SSRF/Node.js fetch() SSRF

Does Node.js fetch() prevent server-side request forgery (SSRF)?

CWE-918: Server-Side Request ForgeryNode.js security reference
Plain English

No. Server-side fetch() makes a network request from the server. If a caller chooses the destination, they may steer that request toward systems the server can reach but the caller cannot. It is like asking a trusted office courier to deliver a parcel without checking the address. The exposure depends on the server's network position, credentials, URL policy, and redirect behavior.

SSRF (CWE-918)A server makes a request to a destination selected or influenced by an untrusted caller, crossing the intended network trust boundary.
Destination allowlistA fixed mapping from a user-facing choice (such as providerId) to a preconfigured origin. It avoids accepting an arbitrary URL.
Redirect validationA response can name a second destination. Automatically following redirects can bypass validation applied only to the initial URL.
DNS rebindingA hostname can resolve to different addresses across lookups. Checking DNS once and letting the HTTP client resolve again creates a time-of-check/time-of-use gap.

Root cause: the server trusts a caller-selected destination

Node.js fetch() is a general-purpose HTTP client, not an SSRF policy engine. It does not decide which networks your application should reach; browser CORS protections do not provide a server-side destination boundary. URL parsing alone is also insufficient: an allowed hostname can resolve to a prohibited address, and a response can redirect to another host. A vulnerable feature might fetch a user-supplied avatar, webhook, document, or preview URL.

How the request crosses the trust boundary

Step 1

A caller influences a URL

An endpoint accepts a complete URL or enough host data to construct one, for example for an image preview.

Step 2

The server sends the request

The server-side HTTP client uses the service network path, DNS, proxy configuration, and identity available to the process.

Step 3

A redirect may change the destination

Fetch follows redirects by default. A destination that passed an initial check may return a Location pointing somewhere the application meant to forbid.

Step 4

The response may expose reachable data

If policy and network controls permit access, internal services or cloud metadata may be reachable. The result depends on the environment and service configuration; it is not automatic for every fetch call.

Vulnerable and safer Node.js patterns

server.js (Caller controls the destination)Vulnerable
// Do not fetch an arbitrary caller-supplied URL.
const response = await fetch(userProvidedUrl);
server.js (Fixed destination mapping)Safer
// The caller selects a key, never a network destination.
const destinations = new Map([
  ["status", new URL("https://status.example/")],
  ["docs", new URL("https://docs.example/")],
]);

const target = destinations.get(providerId);
if (!target) throw new Error("Unknown provider");

const response = await fetch(target, {
  redirect: "error",
  signal: AbortSignal.timeout(3000),
});
if (!response.ok) throw new Error("Upstream request failed");

When users must submit URLs

Prefer a product design that accepts a provider ID and builds the request from a fixed destination map. If arbitrary public URLs are essential, allow only required schemes and ports; reject user-info, loopback, private, link-local, and other prohibited IPv4 and IPv6 destinations; resolve and validate every address; and ensure the client connects to a validated address without a second unchecked lookup. Disable automatic redirects or revalidate every hop. Enforce outbound network rules independently, including blocks for cloud metadata endpoints such as 169.254.169.254 and the enabled IPv6 metadata address. Bound connection time, response size, and concurrency; never forward internal credentials to the fetched host.

SSRF prevention checklist

Frequently asked questions

Is blocking localhost and private IPs enough?

No. Redirects, IPv4 and IPv6 representations, DNS rebinding, proxies, and resolution/connection races can defeat a simple check. Prefer a fixed destination allowlist. When arbitrary destinations are required, validate every resolved address and make the connection use that validated result; enforce the same policy at network egress.

Does requiring IMDSv2 eliminate SSRF?

No. IMDSv2 requires a token flow and can reduce exposure to some SSRF paths, but SSRF can target other internal services or metadata endpoints under different configurations. Keep destination and egress controls in place.

Primary sources

Explore related security topics and incident analyses:Complete Security Directory →
See also Server-Side Request Forgery (SSRF, CWE-918): How It Works and How to Prevent It in Every Language — flawopen.com SSRF and Cloud Metadata: Credential Risks and Defenses AI PR Bots: Prevent Prompt Injection SSRF