Já algum tempo, as tecnologias frontend têm avançado em direção à se tornarem tecnologias full stack, demandando ao desenvolvedor conhecimento técnico tanto do browser quanto da aplicação sendo executada no servidor. Por conta disso alguns pontos de atenção nos vêm à tona, como por exemplo: ataques SSRF.

Introdução – o que é SSRF?
SSRF (Server-Side Request Forgery) é uma vulnerabilidade em que um atacante consegue fazer com que o servidor da aplicação realize requisições HTTP arbitrárias. Isso é crítico porque transforma o servidor confiável em um agente malicioso, permitindo o acesso a recursos internos como:
- Painéis administrativos internos (
http://127.0.0.1/admin-status); - Serviços de metadados em nuvem (ex.: AWS IMDS em
http://169.254.169.254/); - Outras APIs privadas que não deveriam ser expostas.
Em frameworks modernos como Next.js (nas API Routes) e Remix (em Loaders e Actions), o risco é real: qualquer lógica de servidor que aceite entrada do usuário e faça requisições externas pode ser explorada.
O Cenário de Risco (Exemplo de Código Vulnerável)
Imagine que você quer implementar um gerador de preview de links. O código abaixo parece inofensivo:
// exemplo vulnerável (Next.js API Route ou Remix Loader)
export async function loader({ request }) {
const url = new URL(request.url).searchParams.get("target");
// ❌ Risco: atacante controla a URL
const response = await fetch(url);
const html = await response.text();
return { htmlPreview: html.substring(0, 200) };
}Um atacante pode enviar:
/api/preview?target=http://127.0.0.1/admin-statusE, com isso, sua aplicação exporia informações internas que jamais deveriam sair do servidor.
Primeira Linha de Defesa: Whitelist de Hostnames
A primeira defesa contra SSRF é nunca confiar no input do usuário. Uma prática segura é permitir apenas domínios específicos (Whitelist).
const ALLOWED_HOSTS = ["example.com", "api.github.com"];
function isValidExternalUrl(urlString: string): boolean {
try {
const url = new URL(urlString);
return ALLOWED_HOSTS.includes(url.hostname);
} catch {
return false;
}
}- ✅ Segurança garantida contra destinos não previstos.
- ❌ Limitação: não resolve sozinha truques de DNS ou redirecionamentos.
Segunda Linha de Defesa: Bloqueio de IP Privado
Mesmo validando o hostname, um atacante pode usar redirecionamentos ou subdomínios maliciosos para contornar a whitelist.
Por isso, é necessário resolver o DNS para um IP real e verificar se o endereço não pertence a redes privadas:
- 10.0.0.0/8
- 172.16.0.0/12
- 192.168.0.0/16
- 127.0.0.0/8 (loopback)
No Node.js, você pode usar bibliotecas como ipaddr.js, porém nada impede de você implementar uma função que valide IPs locais e/ou redes privadas. A título de exemplo, vamos seguir com esta lib:
import dns from "dns/promises";
import ipaddr from "ipaddr.js";
async function isSafeIp(hostname: string): Promise<boolean> {
const addresses = await dns.lookup(hostname, { all: true });
return addresses.every(addr => {
const ip = ipaddr.parse(addr.address);
if (ip.range() === "private" || ip.range() === "loopback") {
return false;
}
return true;
});
}Essa segunda camada reduz drasticamente a superfície de ataque.
Nota Importante: Redirecionamentos Automáticos
Uma prática negligenciada é desabilitar o seguimento automático de redirecionamentos.
Atacantes podem hospedar um domínio aparentemente confiável que, ao ser acessado, redireciona para um IP privado.
No fetch, por exemplo, configure:
await fetch(url, { redirect: "manual" });Isso adiciona mais uma barreira contra SSRF.
Conclusão e Próximos Passos
O SSRF é uma vulnerabilidade crítica porque transforma o servidor em um aliado do atacante.
Em aplicações Next.js e Remix, onde fetch é usado frequentemente em rotas de servidor, a atenção deve ser redobrada.
As camadas de proteção que você deve adotar:
- Whitelist de domínios confiáveis.
- Verificação de IPs privados.
- Bloqueio de redirecionamentos automáticos.
Defesa em profundidade garante que mesmo que uma camada falhe, outra estará presente para mitigar o risco.
A prevenção, neste caso, é muito mais barata (e segura) do que reagir a um incidente de segurança.



