FlawOpen

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

O fetch() do Node.js impede SSRF?

CWE-918: Server-Side Request ForgeryReferência de segurança Node.js
Em linguagem simples

Não. O fetch() no servidor faz uma requisição a partir do servidor. Se o chamador escolhe o destino, pode direcionar a requisição a sistemas que o servidor alcança, mas o chamador não. É como pedir a um mensageiro de confiança que entregue um pacote sem conferir o endereço. A exposição depende da rede, identidade, política de URLs e redirects.

SSRF (CWE-918)O servidor faz uma requisição a um destino escolhido ou influenciado por um chamador não confiável, cruzando a fronteira de confiança da rede.
Lista de destinos permitidosMapeamento fixo de uma escolha do usuário, como providerId, para uma origem configurada pela aplicação. Evita aceitar URLs arbitrárias.
Validação de redirectsUma resposta pode apontar para um segundo destino. Seguir redirects automaticamente pode contornar uma validação aplicada somente à URL inicial.
DNS rebindingUm nome pode resolver para endereços diferentes. Validar DNS uma vez e deixar o cliente resolver novamente cria uma janela TOCTOU.

Causa raiz: o servidor confia no destino escolhido pelo chamador

O fetch() do Node.js é um cliente HTTP geral, não um mecanismo de política contra SSRF. Ele não decide a quais redes sua aplicação pode se conectar; proteções CORS de navegador não criam essa fronteira no servidor. Analisar a URL também não basta: um host permitido pode resolver para um endereço proibido, e uma resposta pode redirecionar para outro host. Recursos que buscam avatar, webhook, documento ou prévia fornecidos pelo usuário podem criar essa exposição.

Como a requisição cruza a fronteira de confiança

Step 1

O chamador influencia a URL

Um endpoint aceita uma URL completa ou dados suficientes para construí-la, por exemplo para gerar uma prévia de imagem.

Step 2

O servidor envia a requisição

O cliente HTTP usa a rota de rede, DNS, proxy e identidade disponíveis ao processo do servidor.

Step 3

Um redirect pode mudar o destino

Por padrão, Fetch segue redirects. Um destino aprovado inicialmente pode responder com Location para um host que a aplicação deveria bloquear.

Step 4

A resposta pode expor dados alcançáveis

Se a política e a rede permitirem, serviços internos ou metadados de nuvem podem ser alcançados. Isso depende do ambiente; não ocorre automaticamente em toda chamada.

Padrões Node.js vulnerável e mais seguro

Vulnerável
// Não busque uma URL arbitrária fornecida pelo chamador.
const response = await fetch(userProvidedUrl);
Mais seguro
// O chamador escolhe uma chave, nunca um destino de rede.
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");

Quando usuários precisam enviar URLs

Prefira aceitar um identificador de provedor e montar a requisição a partir de um mapa fixo de destinos. Se URLs públicas arbitrárias forem essenciais, permita apenas esquemas e portas necessários; rejeite user-info, loopback, IPs privados, link-local e outros destinos IPv4/IPv6 proibidos; valide todos os endereços resolvidos e garanta que a conexão use um endereço validado sem nova resolução não verificada. Desative redirects automáticos ou valide cada salto. Aplique regras independentes de saída de rede, incluindo bloqueios a endpoints de metadados como 169.254.169.254 e o endpoint IPv6 habilitado. Limite tempo de conexão, tamanho da resposta e concorrência; não encaminhe credenciais internas ao host buscado.

Checklist de prevenção de SSRF

Perguntas frequentes

Bloquear localhost e IPs privados basta?

Não. Redirects, formas alternativas de IPv4/IPv6, DNS rebinding, proxies e corridas entre resolução e conexão podem contornar uma verificação simples. Prefira uma lista de destinos permitidos. Se destinos arbitrários forem necessários, valide cada endereço resolvido e faça a conexão usar esse resultado; aplique a mesma regra na saída de rede.

Exigir IMDSv2 elimina SSRF?

Não. IMDSv2 exige um fluxo com token e reduz algumas exposições, mas SSRF ainda pode atingir outros serviços internos ou endpoints de metadados sob outras configurações. Mantenha controles de destino e de saída.

Fontes primárias

Explore temas de segurança e análises de incidentes relacionados:Diretório completo de segurança →
Veja também Falsificação de requisição do lado do servidor (SSRF, CWE-918): como funciona e como evitar em todas as linguagens — flawopen.com SSRF e metadados de nuvem: riscos e defesas Bots de PR com IA: prevenção de SSRF — flawopen.com