Bij een SSRF-lek valt de aanvaller de machine die hem interesseert niet rechtstreeks aan: hij gebruikt de site als tussenpersoon. De webserver staat vaak in een netwerk waar hij diensten kan bereiken die niemand vanaf internet zou mogen bereiken. Als een functie van de site een adres downloadt dat de gebruiker opgeeft, zonder de bestemming te controleren, kan de aanvaller die diensten via de server laten opvragen. OWASP maakte van SSRF een eigen categorie in de Top 10 van 2021 (A10) en MITRE registreert het onder CWE-918.
Hoe een SSRF-aanval werkt
Het gaat om functies die een URL ophalen: een afbeelding importeren vanaf een adres, een linkvoorbeeld maken, een webhook aanroepen, een feed controleren. De aanvaller vult daar een intern adres in plaats van een openbaar adres in:
- het metadata-adres van de cloud
169.254.169.254, gebruikt door AWS, Azure en Google Cloud, dat inloggegevens en toegangstokens kan prijsgeven; - de server zelf (
localhost,127.0.0.1), bijvoorbeeld een beheerpaneel of een database die alleen lokaal luistert; - het privénetwerk (
10.0.0.0/8,192.168.0.0/16...), om de machines en open poorten in kaart te brengen; - andere protocollen dan HTTP, zoals
file://ofgopher://, als de gebruikte bibliotheek ze accepteert.

Het antwoord komt niet altijd zichtbaar terug: je spreekt van "blinde" SSRF wanneer de aanvaller alleen een foutmelding of een reactietijd ziet. Dat is toch genoeg om te weten of een poort openstaat.
Hoe je je ertegen beschermt
- Allowlist: als de bestemmingen bekend zijn (een specifieke API), accepteer dan alleen die.
- Alleen http en https, op standaardpoorten.
- Interne adressen weigeren na de DNS-resolutie, en ook elke redirect controleren: een openbare domeinnaam kan naar een privéadres wijzen.
- Bij de hosting: netwerksegmentatie en, op AWS, de overstap naar IMDSv2, die OWASP aanraadt om diefstal van metadata te beperken.
Voor WordPress: wp_safe_remote_get en pingbacks
WordPress levert de juiste hulpmiddelen, als je ze gebruikt. wp_safe_remote_get() en de varianten valideren de URL en elke redirect-URL met wp_http_validate_url(): alleen http en https komen erdoor, inloggegevens in de URL worden geweigerd, loopback- en privéadressen worden afgewezen en een expliciete poort moet 80, 443 of 8080 zijn. wp_remote_get() doet die validatie standaard niet: een plugin die deze functie gebruikt met een adres van een bezoeker loopt risico. Met de filter http_request_host_is_external kun je één specifieke interne host toestaan; zet je hem voor alles open, dan valt de bescherming weg.
$antwoord = wp_safe_remote_get( esc_url_raw( $opgegeven_url ), array( 'timeout' => 5 ) );
if ( is_wp_error( $antwoord ) ) {
return; // URL geweigerd of onbereikbaar
}
De core heeft dit probleem zelf gekend: vóór WordPress 3.5.1 kon je via de pingback van XML-RPC verzoeken naar interne servers sturen en poorten scannen (CVE-2013-0235). De pingback gebruikt nu wp_safe_remote_get(), maar blijft een functie die je server verzoeken laat versturen op vraag van een derde. Gebruik je hem niet, dan blokkeert de module Hardening van WP Masquerade gratis pingbacks en XML-RPC; ons artikel over XML-RPC helpt je te controleren of geen enkele dienst ervan afhangt. Voor de rest los je SSRF op in de code van de betrokken plugin, en kan een web application firewall in de tussentijd de duidelijkste interne adressen filteren.