Pular para o conteúdo

SSRF: como evitar que uma aplicação vire ponte para a rede interna

Entenda como uma URL controlada pelo usuário pode alcançar serviços internos e veja um checklist prático de prevenção contra SSRF.

Fluxo comum de uma requisição SSRF até um recurso interno

Fluxo comum de SSRF. Crédito: OWASP Cheat Sheet Series

Uma função de preview pode virar uma ponte para a rede interna. A pessoa cola uma URL, o servidor busca a página e devolve título, imagem e descrição. O problema surge quando esse servidor também enxerga endereços restritos. SSRF é a falsificação de requisição do lado do servidor: a aplicação faz a conexão em nome de quem enviou a URL.

A OWASP explica o cenário e as defesas na sua Cheat Sheet de Server-Side Request Forgery. Um importador, webhook, leitor de feeds, gerador de miniatura ou conversor de documentos pode ser o ponto de entrada. O atacante não precisa controlar a rede; basta encontrar uma função que faça requisições.

Fluxo comum de uma requisição SSRF até um recurso interno
Fluxo comum de SSRF. Crédito: OWASP Cheat Sheet Series.

Como o SSRF aparece no código

Imagine um importador que recebe um endereço e usa uma biblioteca HTTP para baixar o conteúdo. O caminho feliz é simples, mas a mesma função pode receber um endereço local, um nome de serviço da nuvem ou um domínio que redireciona para um IP privado.

Uma tentativa comum é rejeitar localhost e 127.0.0.1. Ela é insuficiente. A rede privada inclui 10.0.0.0/8, 172.16.0.0/12 e 192.168.0.0/16, além de loopback, link-local e IPv6. A validação precisa considerar o endereço resolvido, não apenas o texto digitado.

Bloquear localhost não resolve

Se o DNS mudar entre a checagem e a conexão, a aplicação valida uma resposta e conecta em outra. Esse intervalo é conhecido como rebind de DNS. Interprete a URL com uma biblioteca confiável, aceite só os esquemas necessários, separe host e porta e verifique cada endereço resultante.

Se o recurso só precisa conversar com três serviços, permita esses três destinos. Uma allowlist de hosts conhecidos reduz a superfície de ataque, mas deve vir depois da análise completa da URL. Não use comparação ingênua de texto: um domínio de terceiro pode terminar com o nome da empresa.

Allowlist quando o destino é conhecido

Quando a busca é arbitrária, a rede precisa assumir parte da proteção. O processo pode ficar isolado, sem rota para a rede administrativa, para metadados e para serviços que não fazem parte da tarefa. Redirecionamentos também precisam ser reavaliados.

A aplicação deve aplicar uma política de saída. Firewall ou security group podem negar tráfego para redes privadas, interfaces de administração e serviços de metadados. Em nuvem, proteja o endpoint de metadados conforme a recomendação do provedor.

Defesa em camadas

O cliente HTTP precisa de timeout de conexão e leitura, limite de resposta, limite de redirecionamentos e protocolos permitidos. Desative esquemas desnecessários, como file, ftp e gopher. Logs devem ajudar na investigação sem guardar tokens, cookies ou dados sensíveis.

Um worker com permissões menores reduz o estrago quando uma validação escapar. Essa separação não substitui a checagem da URL; é um freio adicional contra falhas de configuração.

Checklist antes de colocar a função no ar

Liste cada ponto que recebe URL e confirme se precisa buscar um destino fornecido pelo usuário. Registre protocolos, hosts, portas e caminhos necessários. Se o conjunto for pequeno, crie uma allowlist. Se for amplo, documente a necessidade e o ambiente isolado.

Teste URLs públicas, destinos internos bloqueados, redirecionamentos, DNS com múltiplos endereços e respostas grandes em ambiente controlado. Verifique o que aparece nos logs e se a mensagem não vaza o endereço interno nem o corpo retornado.

Fluxo de proteção na camada de rede para impedir requisições SSRF
Defesa na camada de rede. Crédito: OWASP Cheat Sheet Series.
  • Valide esquema, host, porta e destino resolvido.
  • Bloqueie redes internas quando não forem necessárias.
  • Reavalie redirecionamentos e mudanças de DNS.
  • Aplique limites de tempo e tamanho.
  • Proteja a rede e os endpoints de metadados.

O que revisar no fluxo de requisição

O ponto mais fácil de esquecer é a diferença entre validar uma URL e controlar uma conexão. A validação deve acontecer antes da chamada HTTP, mas a configuração do cliente também importa. Um proxy, uma biblioteca ou um redirecionamento pode mudar o caminho que os dados percorrem. Documente esse fluxo para que a revisão não fique limitada à função que recebe o texto.

Também vale decidir se a resposta inteira precisa voltar para o usuário. Em muitos previews, o sistema só precisa de alguns cabeçalhos e de uma pequena parte do documento. Limitar o tamanho reduz consumo de recursos e evita que uma resposta enorme vire outro problema. Se a aplicação baixa arquivos, defina tipos permitidos e não entregue o arquivo ao navegador sem uma checagem adicional.

Mensagens de erro merecem o mesmo cuidado. Um timeout, um código de DNS ou o endereço final podem ajudar quem está testando a função a mapear a rede. Para o usuário, uma mensagem curta basta. Nos registros internos, guarde apenas os dados necessários, aplique retenção e restrinja o acesso à equipe que investiga incidentes.

Em revisão de código, procure chamadas como get, post ou request que recebem diretamente um parâmetro de URL. Siga a variável até a origem e confira se existe uma política central, não uma coleção de filtros espalhados. Um utilitário único facilita testes e reduz a chance de uma nova funcionalidade esquecer a defesa.

Por fim, inclua o caso no modelo de ameaça da aplicação. O risco muda quando o serviço roda em uma máquina local, em um cluster ou em uma nuvem com identidade anexada. A mesma URL pode ser apenas um erro em um ambiente e uma forma de alcançar credenciais em outro. A rede e as permissões devem refletir esse impacto.

Fonte oficial: OWASP Cheat Sheet Series.

Resumo da semana

Leve contexto para a caixa de entrada.

Uma edição semanal, sem barulho e sem promessas vazias.