La Server-Side Request Forgery è una tecnica di exploiting che permette a un attaccante di far eseguire richieste HTTP dal server verso destinazioni arbitrarie. Ovvero? In sostanza si verifica quando una web app, richiede una risorsa remota senza verificare e validare l’URL fornito dall’utente.
SSRF è stata la chiave d'accesso per alcune delle violazioni più gravi degli ultimi anni, inclusa la breach di Capital One che ha esposto oltre 100 milioni di record.
Come funziona
Quando un'applicazione web accetta un URL dall'utente e lo recupera lato server, si crea il presupposto per SSRF. Esempi comuni:
- Import di immagini da URL
- Webhook e callback configurabili
- Parser di feed RSS/XML
- Generatori di PDF che caricano risorse esterne
- Proxy e URL shortener
Il server, fidandosi dell'input, effettua la richiesta. Se l'attaccante fornisce un URL che punta a risorse interne, il server diventa un proxy involontario verso l'infrastruttura protetta.
Richiesta legittima:
POST /api/fetch-image
{"url": "https://example.com/logo.png"}
Richiesta malevola:
POST /api/fetch-image
{"url": "http://169.254.169.254/latest/meta-data/"}
Perché 169.254.169.254 fa paura
Quell'indirizzo IP è il metadata service dei cloud provider (AWS, GCP, Azure). Da una macchina EC2 è raggiungibile solo internamente e restituisce informazioni sensibili: credenziali IAM temporanee, chiavi API, token di sessione.
Un SSRF che raggiunge il metadata service può estrarre credenziali con permessi elevati. Da lì l'attaccante accede a S3 bucket, database RDS, secrets manager. Il perimetro di rete crolla.
AWS ha introdotto IMDSv2 che richiede un token per accedere ai metadata, ma molte istanze usano ancora v1 o hanno v2 configurato come opzionale.
Bypass dei filtri
La prima reazione degli sviluppatori è filtrare gli URL. Bloccare localhost, 127.0.0.1, indirizzi privati. Funziona? Raramente.
DNS Rebinding: l'attaccante controlla un dominio che inizialmente risolve a un IP pubblico (passa il filtro) e poi cambia risoluzione verso un IP interno. Il server ha già validato l'URL, la richiesta parte verso l'indirizzo interno.
Encoding e rappresentazioni alternative:
127.0.0.1diventa2130706433(decimale)127.0.0.1diventa0x7f000001(esadecimale)localhostdiventalocaltest.me(dominio pubblico che risolve a 127.0.0.1)- IPv6:
[::]equivale a0.0.0.0
Redirect chain: l'URL punta a un server controllato dall'attaccante che risponde con un redirect 302 verso la destinazione interna. Il filtro valida solo l'URL iniziale.
URL parser inconsistencies: differenze tra come il filtro parsa l'URL e come lo interpreta la libreria HTTP. Caratteri come @, #, encoding multipli possono confondere la validazione.
http://attacker.com#@internal-server/admin
http://internal-server:[email protected]/
http://attacker.com/?url=http://internal-server/
Da SSRF a RCE
SSRF diventa critico quando raggiunge servizi interni privi di autenticazione:
Redis (porta 6379): molte installazioni non richiedono password. Con il protocollo RESP è possibile iniettare comandi attraverso una richiesta HTTP malformata. Scrivere una chiave con una cron job o una SSH key porta a RCE.
Memcached (porta 11211): stesso principio. Injection di dati serializzati che verranno deserializzati dall'applicazione.
Docker API (porta 2375): se esposta senza TLS, permette di creare container privilegiati, montare il filesystem host, eseguire comandi come root.
Consul, etcd, Kubernetes API: servizi di orchestrazione spesso accessibili senza autenticazione dalla rete interna. Lettura di secrets, configurazioni, possibilità di deployment malevoli.
Elasticsearch (porta 9200): lettura e scrittura di indici, potenziale accesso a log e dati sensibili.
Testing
Identificare SSRF richiede un server che riceva le callback. Burp Collaborator fa questo lavoro: genera URL unici e notifica quando ricevono richieste.
Alternative gratuite:
- interactsh (ProjectDiscovery)
- webhook.site
- requestbin.com
Parametri da testare:
- Qualsiasi campo che accetta URL
- Header come
X-Forwarded-For,Referer(in alcuni casi processati lato server) - Parametri nascosti scoperti tramite fuzzing
Payload iniziali:
http://collaborator-url/
http://169.254.169.254/latest/meta-data/
http://[::]:22/
http://127.0.0.1:6379/
Mitigazione
Whitelist, non blacklist: a livello di firewall bisogna imporre delle policies di tipo deny all (nega tutto) o delle ACL molto stringenti per bloccare tutto il traffico non essenziale.
Validazione post-risoluzione DNS: verificare l'IP di destinazione dopo la risoluzione DNS, non solo l'URL in input. Bloccare range privati (10.x, 172.16-31.x, 192.168.x, 169.254.x, 127.x).
Disabilitare redirect: se non necessari, impedire che la libreria HTTP segua redirect automaticamente.
Network segmentation: isolare i server applicativi dai servizi interni critici. Il metadata service dovrebbe essere raggiungibile solo dalle istanze che ne hanno bisogno.
IMDSv2 su AWS: forzare l'uso del token per l'accesso ai metadata. Non lasciare v1 come fallback.
Timeout e rate limiting: limitare il numero di richieste esterne e il tempo di attesa. Rallenta l'exploitation e rende evidenti i tentativi di scansione.
Riferimenti
- OWASP SSRF Prevention Cheat Sheet
- PortSwigger Web Security Academy - SSRF
- HackerOne Reports (filtrare per SSRF)
- Capital One Breach Analysis (Krebs on Security)