Como causar impacto com SSRF
O desenvolvedor permite que o cliente dispare uma requisição a partir de um servidor dele. Seja para um webhook na plataforma dele, seja de outra forma, mas o ponto é: O usuário tem controle da URL para onde uma requisição será disparada a partir do servidor.
Exemplo: digamos que o usuário consiga criar um webhook que o servidor da aplicação dispara quando um determinado evento na plataforma acontece.
Essa é a premissa para uma vulnerabilidade chamada SSRF (Server-Side Request Forgery), que é quando um atacante consegue controlar/manipular uma requisição disparada pelo servidor.
Isso pode até parecer inofensivo por quem não tem muito domínio de redes, mas essa pode ser uma vulnerabilidade crítica que pode até mesmo permitir uma execução remota de código, burlar firewalls, vazar credenciais entre outras coisas.
Cloud provider metadata
Começando com o impacto mais comum de ocorrer na vida real: Cloud providers como Google Cloud (GCP) e AWS expõem uma API de metadados para as instâncias em execução. Por exemplo: a partir de uma instância da GCP, se você enviar uma requisição para http://metadata.google.internal/computeMetadata/v1 você obterá os metadados daquela instância.
Nesses metadados há dados sensíveis, incluindo uma credencial de acesso que dá acesso ao GCP com o nível de acesso que você tiver configurado para a instância. Por padrão, esse acesso é bastante permissivo.
Explorando um SSRF, um atacante pode obter essa credencial e conseguir acesso ao seu cloud provider, incluindo (se estiver com as permissões padrão) acesso a todos os seus servidores e bancos de dados.
Serviços internos
Também é possível usar SSRF para interagir com serviços internos que não estejam com nenhuma proteção via autenticação, o que é comum de ocorrer em ambientes reais porque as pessoas pensam: "só dá para acessar por rede interna, não precisa de autenticação".
Por exemplo: O serviço do Docker funciona com uma API REST HTTP, você pode usar SSRF para iniciar e controlar containers Docker. Incluindo montar volumes dentro do container, dando acesso ao sistema de arquivos da máquina real a partir do container.
Protocolos sensíveis
Você pode usar SSRF para ler arquivos em disco usando protocolos como file:// ou ftp://. Se a aplicação for em PHP, em alguns cenários específicos você pode usar o pseudo-protocolo php:// com várias finalidades, incluindo a leitura de arquivos.
O protocolo gopher:// permite enviar pacotes TCP com conteúdo totalmente personalizado. Isso permite interagir com qualquer serviço TCP que não usa HTTP, como é o caso do Redis. Mas para isso ser possível, vai depender da tecnologia usada no backend suportar o schema gopher. O curl suporta, por exemplo.
Uma requisição como gopher://127.0.0.1:6379/_KEYS%20*%0d%0a poderia ser usada para enviar o comando KEYS * para o Redis.
Deny list bypass
Um erro comum de desenvolvedores é evitar requisições sensíveis fazendo uma lista de IPs e domínios que não devem ser aceitos na URL. Por exemplo, negar coisas como: 127.0.0.1, localhost, metadata.google.internal etc.
Isso é tão útil quanto não fazer nada. Aulinha rápida de DNS: Você pode criar um registro A apontando para qualquer IP que você quiser... Qualquer IP... Literalmente qualquer IP, incluindo IP de rede interna e 127.0.0.1.
Então se sua aplicação nega 127.0.0.1 e localhost, de nada adianta. O atacante cria um registro A como tepeguei.exemplo.com apontando para 127.0.0.1 e pronto: quando seu app resolver esse domínio ele irá apontar para o localhost.
Também é possível criar um registro CNAME apontando para domínios internos como metadata.google.internal e o resultado seria o mesmo: seu app resolveria para o domínio interno e a sua deny list ficaria só como enfeite.
Mitigação
Obrigue o uso de protocolos específicos como http:// e https://. Depois disso, não dispare a requisição a partir de uma máquina com acesso livre à sua rede interna. Faça network isolation na máquina, VM/MicroVM ou container onde a requisição controlada pelo usuário irá ser disparada.
Use firewall para impedir requisições para a rede interna e API de metadados do cloud provider, bloquear protocolos e tudo mais. Limite o acesso à rede o máximo que for possível limitar sem quebrar a funcionalidade da aplicação.