
Indice dei contenuti
Un’applicazione ti chiede di inserire l’indirizzo di un’immagine e promette di scaricarla automaticamente. Oppure un servizio accetta un URL per verificare un sito, generare un’anteprima o inviare una richiesta. Funzioni normalissime, che però nascondono una domanda importante: chi decide davvero dove si collegherà il server? 🎣
È da qui che nasce una classe di vulnerabilità chiamata Server-Side Request Forgery, abbreviata in SSRF. Il nome è tecnico, ma l’idea è semplice: un attaccante prova a convincere il server a effettuare richieste verso destinazioni che non dovrebbe raggiungere.
Un esempio per capire il problema
Immagina un’applicazione che riceve un URL e scarica l’immagine corrispondente. Se accetta qualsiasi indirizzo senza controlli, potrebbe essere indotta a contattare risorse interne alla rete, servizi locali o endpoint amministrativi non destinati agli utenti pubblici.
Il punto critico è che la richiesta non parte dal browser dell’utente, ma dal server dell’applicazione. Quel server potrebbe avere una visibilità di rete diversa e privilegi di accesso che un visitatore esterno non possiede.
Non serve necessariamente che il sistema restituisca tutto il contenuto della risposta: in alcuni casi anche differenze nei tempi di risposta o nei messaggi d’errore possono rivelare informazioni utili a chi attacca.
Dove può nascondersi una SSRF? 🔍
Le superfici più comuni sono funzioni che accettano indirizzi esterni: importatori di immagini, generatori di anteprime, sistemi di screenshot, verificatori di link, conversioni da URL a PDF, integrazioni webhook e strumenti di monitoraggio.
Il rischio non dipende dal fatto che una funzione sia “avanzata”. Anche una piccola utility realizzata in PHP può diventare pericolosa se scarica risorse arbitrarie senza distinguere tra destinazioni consentite e vietate.
Perché bloccare soltanto localhost non basta
Un primo impulso potrebbe essere rifiutare gli URL che contengono la parola localhost. Purtroppo non è una difesa sufficiente. Le destinazioni possono essere rappresentate in modi differenti, gli hostname possono risolversi verso indirizzi inattesi e i redirect possono spostare la richiesta su un altro host.
Per questo una protezione seria deve considerare la risoluzione DNS, gli indirizzi IP effettivi, i redirect e il comportamento della libreria HTTP utilizzata. Non basta controllare che una stringa “sembri un sito web”.
La difesa migliore è sapere quali destinazioni servono davvero 🛡️
Se l’applicazione deve comunicare soltanto con un servizio preciso, l’approccio più robusto è mantenere un elenco di destinazioni esplicitamente autorizzate. Invece di accettare URL arbitrarie, l’applicazione può costruire internamente la richiesta verso l’API prevista.
Quando è indispensabile accettare URL inserite dagli utenti, il problema diventa più complesso. Bisogna validare schema e destinazione, impedire l’accesso a reti e indirizzi riservati non necessari, controllare nuovamente le destinazioni dopo i redirect e limitare le capacità di rete del processo.
Una difesa a livello applicativo è utile, ma non dovrebbe essere l’unica barriera: anche le regole di rete in uscita possono impedire a un servizio compromesso di raggiungere risorse interne sensibili.
Importatori di immagini e WordPress 📸
Nei CMS capita spesso di importare media da URL esterni. È una funzione comoda, soprattutto quando si gestiscono molti contenuti. Tuttavia ogni importazione comporta una richiesta effettuata dal server, e quindi merita controlli adeguati.
Su WordPress conviene preferire le funzioni e le API che prevedono validazioni delle URL, mantenere aggiornati plugin e librerie e limitare gli endpoint che consentono download remoti agli utenti effettivamente autorizzati.
Una funzione che importa immagini non dovrebbe trasformarsi in un proxy generico accessibile a chiunque. Anche dimensioni massime, timeout e limiti sui download aiutano a ridurre abusi e consumo incontrollato di risorse.
E i webhook? 🔔
I webhook meritano un’attenzione particolare perché, per definizione, collegano servizi differenti. Se un utente può scegliere liberamente l’URL di destinazione, è importante valutare quali reti siano raggiungibili dal server che invia la richiesta.
Un sistema robusto dovrebbe distinguere tra endpoint esterni legittimi e destinazioni interne, gestire con cautela i redirect e utilizzare timeout ragionevoli. La firma dei webhook protegge l’autenticità del messaggio, ma non risolve da sola il problema SSRF: sono due controlli con finalità diverse.
Gli errori più comuni ❌
- Accettare qualsiasi URL senza validare la destinazione.
- Controllare solo il nome host e ignorare l’indirizzo IP risolto.
- Seguire redirect senza verificare dove conducono.
- Consentire al processo applicativo accessi di rete più ampi del necessario.
- Restituire all’utente dettagli sensibili sulle risposte dei servizi interni.
- Affidarsi a una singola blacklist di parole proibite.
Come imposterei una verifica pratica 🧪
Partirei dall’inventario delle funzionalità che effettuano richieste HTTP verso indirizzi forniti dagli utenti. Per ognuna identificherei gli schemi ammessi, le destinazioni previste, i permessi richiesti e le regole di rete. Poi controllerei timeout, dimensione massima delle risposte, gestione dei redirect e messaggi di errore.
Il tutto in un ambiente di test, senza lanciare prove invasive su servizi di terzi. È lo stesso approccio prudente che consiglio nell’articolo sullo staging WordPress e in quello sull’hardening della VPS.
Un riferimento utile per approfondire
La SSRF Prevention Cheat Sheet di OWASP raccoglie raccomandazioni tecniche e distingue scenari in cui le destinazioni sono note da quelli in cui devono essere più flessibili.
La lezione è semplice: quando un’applicazione può chiamare un URL, sta usando la propria posizione nella rete per conto di qualcun altro. E quella capacità va trattata come un permesso sensibile, non come una banale operazione di download. 🌍
