Zero-Day & Exploits
SSRF na cloud: por que validar a URL não protege sua API
DNS, redirects, IPv6 e metadados cloud: um roteiro para controlar a saída de rede, testar SSRF localmente e registrar o impacto comprovado.
SSRF ocorre quando uma aplicação realiza uma conexão que o usuário não deveria controlar. Importadores de imagens, webhooks, geradores de PDF e integrações que recebem URLs merecem atenção porque conectam dados fornecidos pelo cliente à rede disponível para o servidor. Na cloud, essa fronteira pode envolver serviços internos e credenciais de workloads.
O desafio não termina em reconhecer uma URL válida. O destino efetivo depende de resolução DNS, redirecionamentos, portas e do comportamento do cliente HTTP. Este guia organiza essas camadas e propõe testes locais para distinguir uma configuração arriscada de um impacto realmente demonstrado.
DNS e conexão: o intervalo entre validar e usar
O problema mais traiçoeiro é temporal. A aplicação resolve um nome, decide que o endereço é permitido e depois entrega o hostname a outra biblioteca, que resolve novamente. O endereço usado pode ser diferente do endereço aprovado. Essa condição é um caso de time of check, time of use: a política verificou um objeto e a conexão usou outro.
A rotina abaixo apenas classifica endereços em memória. É uma peça didática, não um cliente HTTP seguro completo. Ela recusa respostas contendo algum endereço fora da política, inclusive IPv4 representado em IPv6. O laboratório inclui uma resposta DNS que mistura público e loopback para testar uma decisão conservadora.
import ipaddress
def resposta_permitida(enderecos):
if not enderecos:
return False
for texto in enderecos:
ip = ipaddress.ip_address(texto)
if isinstance(ip, ipaddress.IPv6Address) and ip.ipv4_mapped:
ip = ip.ipv4_mapped
if not ip.is_global:
return False
return True
assert not resposta_permitida(['127.0.0.1'])
assert not resposta_permitida(['::ffff:127.0.0.1'])
assert not resposta_permitida(['8.8.8.8', '127.0.0.1'])
O loop verifica cada resposta, não somente a primeira. Entretanto, is_global é um filtro inicial e não substitui o escopo contratual: um IP público pode pertencer a um serviço proibido. Em produção, a decisão deve incluir uma allowlist autoritativa, protocolos, portas e redes explicitamente aprovadas, com atenção às tabelas de endereços especiais da versão usada.
Depois da aprovação, o transporte precisa conectar ao endereço autorizado sem uma resolução independente, preservando o hostname correto em SNI e na validação do certificado. Proxy de saída, pool de conexões e redirecionamentos também entram nessa garantia. Desabilitar TLS para conseguir conectar ao IP destrói outra fronteira de segurança.
Em um redirecionamento, o novo destino é uma nova decisão: normalize, resolva, valide e aplique orçamento novamente. O teste deve observar o endereço realmente conectado no intermediário de saída. Um log contendo a URL original não prova isso. Limite também bytes recebidos, tempo, quantidade de redirects e esquemas aceitos; a proteção deve continuar válida durante toda a operação.
Uma URL válida pode apontar para um destino indevido
A orientação da OWASP para prevenção de SSRF aborda validação de destinos e proteção da camada de rede. Ela recomenda examinar endereços IPv4 e IPv6, considerar as respostas DNS e vincular a conexão a um endereço validado. Consultar o DNS e deixar o cliente resolver novamente não elimina DNS rebinding.
Redirecionamentos também exigem uma decisão explícita. Um domínio inicialmente permitido pode responder com um destino diferente. O componente que efetivamente abre a conexão deve aplicar a política a cada etapa; uma validação isolada no formulário não acompanha essa mudança.
Modele a saída de rede como uma capacidade limitada
Em vez de fornecer um cliente HTTP irrestrito a cada integração, um desenho proposto é centralizar a saída em um intermediário. Ele recebe a operação necessária, normaliza o destino e decide se pode conectá-lo. Esse componente precisa controlar o tráfego real, não apenas registrar decisões enquanto a aplicação mantém outra rota de saída.
Entrada fornecida pelo usuário
↓
Normalização e política de destino
↓
Resolução DNS e endereço validado
↓
Conexão ao endereço aprovado
↓
Revalidação de cada redirecionamento
↓
Resposta limitada em tamanho e duração
Para uma integração com destinos conhecidos, prefira uma lista explícita de serviços e operações. Para um importador que precisa acessar a internet, estabeleça uma política distinta: protocolos permitidos, portas, redes excluídas, quantidade de redirecionamentos e orçamento da resposta. Exceções internas devem ter finalidade e responsável.
Limite tempo, tamanho de corpo e concorrência para impedir que uma chamada aparentemente simples ocupe recursos por tempo indefinido. Não encaminhe cookies ou cabeçalhos de autenticação a um novo host durante um redirecionamento sem uma autorização específica para esse destino.
IMDSv2 ajuda, mas não substitui a correção da aplicação
O serviço de metadados do EC2 pode fornecer informações da instância e credenciais temporárias da role associada. A documentação do IMDS descreve o modo IMDSv2, baseado em um token de sessão obtido antes da consulta. Exigir esse modo impede o uso do fluxo antigo sem token.
A AWS apresenta o IMDSv2 como defesa em profundidade contra determinadas formas de SSRF e exposição por proxies. Ele adiciona barreiras ao acesso aos metadados, mas não resolve uma integração que alcança outros serviços internos indevidos.
Revise também a permissão da role e a necessidade de acesso aos metadados. O limite de saltos deve ser compatível com a arquitetura real; workloads em containers podem precisar de uma configuração diferente. Um valor escolhido sem entender o caminho de rede pode interromper o funcionamento ou manter uma exposição desnecessária.
O que CloudTrail pode mostrar depois de um incidente
Uma consulta ao serviço de metadados não equivale a uma chamada de API registrada no CloudTrail. A investigação precisa relacionar registros da aplicação e da rede com o uso posterior das credenciais. O guia de investigação da AWS apresenta uma cadeia envolvendo SSRF, credenciais temporárias e atividade subsequente na conta.
Construa uma linha do tempo com horários, role, sessões, chamadas de API e origens observadas. Uma origem incomum merece análise, mas não prova, isoladamente, roubo de credenciais. Se os registros não mostram como ocorreu o acesso inicial, mantenha essa parte como hipótese.
Laboratório local para testar a fronteira de rede
O cenário a seguir é fictício. Monte um importador, um destino permitido e um destino restrito em uma rede isolada. Utilize somente dados sintéticos e um mock de metadados que nunca emita credenciais reais. O roteiro proposto permite verificar a política sem tentar alcançar serviços internos de terceiros.
| Caso | Resultado esperado | Registro necessário |
|---|---|---|
| URL de serviço permitido | Conexão dentro do orçamento | Host, endereço e operação efetivos |
| Redirect para serviço restrito | Bloqueio antes da conexão | Destino original e destino recusado |
| DNS controlado muda de endereço | Política aplicada ao endereço conectado | Resolução e conexão correlacionadas |
| Destino IPv6 não autorizado | Mesma política aplicada ao IPv4 | Classificação e motivo do bloqueio |
| Resposta excede o limite | Encerramento controlado | Bytes, duração e estado da operação |
Um mock que recebeu a conexão confirma que o componente alcançou aquele destino. Isso não comprova acesso a credenciais, movimento lateral ou comprometimento de uma conta. Para sustentar um impacto adicional, a evidência deve mostrar a operação correspondente no laboratório e os controles que deveriam tê-la impedido.
Critérios de encerramento do teste de saída
Um resultado reproduzível deve ligar a URL recebida ao destino realmente conectado. Registre a URL normalizada sem credenciais, a regra de escopo aplicada, os endereços aprovados na resolução, o endereço do par remoto e a decisão para cada redirecionamento. Essa trilha permite descobrir se uma validação correta foi seguida por uma conexão diferente. A orientação de prevenção de SSRF da OWASP trata a validação da aplicação e o controle de rede como camadas complementares.
| Caso controlado | Resultado esperado | Evidência mínima |
|---|---|---|
| Destino dentro do escopo | Conexão somente ao endereço aprovado | Regra aplicada e par remoto correlacionados |
| DNS muda para rede não autorizada | Bloqueio antes da conexão indevida | Nova resolução e decisão de recusa |
| Redirecionamento fora do escopo | Nenhum encaminhamento de sessão ou autorização | Destino recusado e headers sensíveis ausentes |
| Timeout após o envio | Estado de resultado desconhecido | Identidade da operação sem repetição automática |
Use servidores locais de teste e valores fictícios. O código que classifica um IP não comprova que o transporte fixou esse endereço; o reteste deve observar os dois. Ausência de resposta também não comprova bloqueio: pode ser timeout, queda do serviço ou erro de captura. Diferencie esses estados antes de encerrar o finding.
Checklist para revisar uma integração
- Documentar por que o servidor precisa abrir a conexão e quem pode solicitar essa operação.
- Separar destinos públicos, internos e loopback em políticas explícitas.
- Normalizar URL, protocolo, hostname, endereço e porta com bibliotecas apropriadas.
- Garantir que a conexão utiliza o endereço validado, preservando a validação TLS do hostname original.
- Revalidar redirects e impedir compartilhamento involuntário de credenciais.
- Aplicar limites de tempo, tamanho e concorrência na saída real.
- Revisar IMDS, permissões da role e registros da aplicação quando houver EC2.
Perguntas frequentes
Permitir somente HTTPS resolve SSRF?
Não. O protocolo protege o transporte, mas não define se o destino ou a operação são autorizados.
WAF e bloqueio de strings substituem o controle de saída?
Não. São camadas que podem ajudar, enquanto a decisão sobre a conexão deve permanecer no componente capaz de controlar destino, resolução e redirecionamentos.
Como acompanhar o comportamento da aplicação?
Use o guia de interceptação HTTP e HTTPS no CatSuite para observar as mensagens do cliente no laboratório. A saída realizada pelo backend exige registros e instrumentos próprios no servidor; ela não aparece automaticamente em uma captura feita apenas no Android.
Próximo passo: selecione uma integração que aceita URLs e descreva o destino efetivo de cada conexão. Um mapa curto com decisões verificáveis costuma revelar mais do que uma lista extensa de filtros sem evidência de aplicação.