Não existe um único botão que pare o (falsificação de requisição do lado do servidor, do inglês server-side request forgery). As defesas que funcionam são em camadas, e compartilham um tema: decida com base no destino real, não no texto da URL.
Prefira uma allow-list
Se o recurso só precisa alcançar um conjunto conhecido de hosts, permita exatamente esses e rejeite todo o resto. Uma allow-list falha de forma segura: uma grafia que o atacante inventa simplesmente não está na lista. Uma block-list falha de forma aberta, porque só pode barrar os endereços e formas internas que você pensou em listar, e os truques de ofuscação dão ao atacante grafias novas sem fim.
Resolva, verifique, depois fixe
Se você precisa aceitar URLs arbitrárias, resolva o hostname para um IP, classifique esse IP contra as faixas internas e rejeite resultados internos. Depois use o endereço que você validou para a conexão real. Verificar o nome e então conectar pelo nome de novo abre uma janela de tempo-de-verificação para tempo-de-uso chamada DNS rebinding, na qual o nome resolve para um endereço seguro durante a validação e para um interno um instante depois. Valide e conecte-se ao mesmo endereço resolvido.
Trate redirecionamentos e esquemas
Uma primeira URL segura pode redirecionar para http://169.254.169.254/. Ou desabilite redirecionamentos na busca, ou reexecute a classificação completa a cada salto. Restrinja o esquema a http e https para que file://, gopher:// e similares não possam ser usados para escalar.
Adicione controles na camada de rede
Defesa em profundidade significa não depender apenas da aplicação. Bloqueie o tráfego de saída do serviço que faz a busca para faixas internas e para o endereço de metadados na camada de rede ou de firewall, para que um erro de lógica não vire uma invasão. Na , aplique o IMDSv2. O classificador na camada da aplicação, a etapa de resolver-depois-verificar e as regras de saída cada um pega o que os outros deixam passar.
A allow-list que valida um nome e conecta a um endereço
A defesa mais frequentemente derrotada é a que parece correta: resolve o host, confere o endereço contra a política, faz a requisição. Acontecem duas resoluções, e nada garante que devolvam a mesma resposta.
Essa brecha é o DNS rebinding. O atacante controla um nome com curtíssimo; a resolução de validação devolve um endereço público permitido, e a de conexão, instantes depois, devolve 169.254.169.254. Cada linha da checagem rodou corretamente e a requisição foi para onde a política proíbe.
Fechar isso significa checar e conectar contra o mesmo endereço resolvido — resolva uma vez, valide aquele endereço, conecte a ele e não ao nome.
E redirecionamentos reabrem a brecha. Um host permitido respondendo 302 para uma URL interna contorna uma checagem feita só na entrada original. Ou não siga redirecionamentos, ou revalide cada salto — uma política aplicada uma vez a uma cadeia de requisições é uma política aplicada à primeira.