Lühidalt: SSRF-i hoiate PHP-s ära nii, et teie rakendus pärib ainult aadresse, mis on kindlas lubatud nimekirjas, ainult HTTPS-i kaudu, ümbersuunamisi järgimata. Lahendatud IP-aadressi kontrollitakse privaatsete ja reserveeritud vahemike vastu ning seejärel fikseeritakse ühenduse jaoks. Väljamineva liikluse tulemüür hoolitseb selle eest, et sisesüsteemid jäävad kättesaamatuks ka koodiviga korral.
Kui oma server esitab võõrastele päringuid
Linkide eelvaated vestluses, tootepildi import URL-i kaudu, veebikonksud partnersüsteemidele, voolulugeja sisuhaldussüsteemis: paljud PHP-rakendused pärivad aadresse, mille kasutaja on sisestanud. See on kasulik funktsioon ja samal ajal uks sissepoole.
Server-Side Request Forgery ehk SSRF puhul paneb ründaja rakenduse saatma päringu enda valitud sihtkohta. Nipp: päring tuleb serverilt endalt. Sellega jõuab see süsteemideni, mis on väljastpoolt suletud, näiteks andmebaasid, haldusliidesed sisevõrgus, teenused, mis kuulavad ainult localhosti, või pilveteenuse pakkujate metaandmeteenused.
- aasta OWASP Top 10-s oli SSRF omaette kategooria. PHP-projektides ilmub auk sageli sinna, kus keegi on kiiresti ehitanud funktsiooni „lisa pilt URL-i kaudu“.
SSRF PHP-s: millised funktsioonid aadresse pärivad
Aadresse ei päri mitte ainult cURL. Järgmised kohad peaksite silmas pidama:
| Funktsioon või ala | Miks oluline |
|---|---|
cURL (curl_exec()) |
sagedaseim tee, palju protokolle võimalik |
file_get_contents(), fopen(), copy() URL-iga |
kasutavad URL-wrappereid, kui allow_url_fopen on aktiivne |
getimagesize() ja pilditeegid |
võivad laadida kaugfaile |
| XML-töötlus, SOAP-kliendid | laadivad teatud tingimustel väliseid ressursse |
| HTTP-teegid, nagu Guzzle | tuginevad cURL-ile või voogudele, samad reeglid |
Kui teie rakendus ei pea faile failifunktsioonidega kaugelt avama, lülitage allow_url_fopen serveris välja. Seotud teemat, failide kaasamist päringust pärit teede kaudu, käsitleb juhend Local ja Remote File Inclusion'i vältimine.
Kaitse viies sammus
OWASP soovitab meetmete kombinatsiooni, mida üksikult saaks igaühest mööda minna, kuid koos need kannavad:
- Lubatud nimekiri vaba URL-i asemel: Kõige parem on, kui kasutaja valib ainult tuntud sihtkohtade hulgast või annab vaid tunnuse ja rakendus ehitab aadressi ise.
- Lubage ainult HTTPS: Jätke cURL-is välja teised protokollid, nagu
file,gophervõiftp, ka ümbersuunamiste puhul. - Ärge järgige ümbersuunamisi: Lubatud aadress võib muidu suunata sisemisele sihtkohale.
- Kontrollige ja fikseerige lahendatud aadress: Lahendage hostinimi, kontrollige IP-d privaatsete, loopback- ja link-local-vahemike vastu ning kasutage ühenduse jaoks täpselt seda IP-d. Muidu võib teine DNS-lahendus anda teise sihtkoha.
- Piirake võrku: Veebiserver tohib väljapoole jõuda ainult nende sihtkohtadeni, mida ta vajab.
Turvaline muster cURL-iga
Järgmine näide rakendab samme 1 kuni 4 IPv4 jaoks. Hostinimed ja kulg on näited; IPv6 jaoks kehtivad samad kontrollid.
<?php
declare(strict_types=1);
function ladeVonPartner(string $url): string
{
$teile = parse_url($url);
if (!is_array($teile) || ($teile['scheme'] ?? '') !== 'https'
|| isset($teile['user']) || isset($teile['pass']) || isset($teile['port'])) {
throw new InvalidArgumentException('Adresse nicht erlaubt.');
}
$host = strtolower($teile['host'] ?? '');
$erlaubt = ['api.partner.example', 'bilder.partner.example'];
if (!in_array($host, $erlaubt, true)) {
throw new InvalidArgumentException('Ziel nicht erlaubt.');
}
$ip = gethostbyname($host);
$oeffentlich = filter_var($ip, FILTER_VALIDATE_IP,
FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE);
if ($oeffentlich === false) {
throw new RuntimeException('Ziel löst auf eine nicht erlaubte Adresse auf.');
}
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_PROTOCOLS => CURLPROTO_HTTPS,
CURLOPT_REDIR_PROTOCOLS => CURLPROTO_HTTPS,
CURLOPT_RESOLVE => [$host . ':443:' . $ip],
CURLOPT_CONNECTTIMEOUT => 3,
CURLOPT_TIMEOUT => 10,
]);
$antwort = curl_exec($ch);
if ($antwort === false) {
throw new RuntimeException('Abruf fehlgeschlagen.');
}
return $antwort;
}
Mõned üksikasjad on olulised. gethostbyname() tagastab vea korral hostinime; järgnev IP-kontroll püüab selle kinni. Lipud FILTER_FLAG_NO_PRIV_RANGE ja FILTER_FLAG_NO_RES_RANGE jätavad PHP käsiraamatu kohaselt välja muu hulgas vahemikud 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 127.0.0.0/8 ja 169.254.0.0/16. PHP 8.2-st on lisaks FILTER_FLAG_GLOBAL_RANGE, mis lubab ainult globaalselt kehtivaid aadresse. CURLOPT_RESOLVE tagab, et cURL kasutab täpselt kontrollitud aadressi, samal ajal kui hostinimi ja sertifikaadi kontroll säilivad.
Kaks muud punkti piiravad seda, mida ründaja SSRF-august teada saab. Ärge andke päritud sihtkoha vastuseid ja veateateid kasutajale filtreerimata tagasi: juba vahe „ühendus keelduti“ ja „ajalõpp“ vahel reedab, millised sisemised teenused olemas on. Ja piirake vastuse tööaega ja suurust, et funktsioon ei sobiks oma serveri ülekoormamiseks. Veebikonksud aadressidele, mille kliendid ise sisestavad, saatke kõige parem järjekorrast ja mitte käimasoleva päringu ajal.
Kui teie rakendus peab tõesti pärima suvalisi aadresse, näiteks linkide eelvaadete jaoks, viige see funktsioon eraldi teenusesse ilma ligipääsuta sisevõrku. Lubatud nimekiri ei ole siis võimalik, võrgu eraldamine on seda olulisem.
Võrgutase turvavõrguna
Koodikontrollidel võivad olla augud, näiteks kui kaks teeki lahutavad URL-i erinevalt. OWASP soovitab selliseid lahknevusi käsitleda tagasilükkamisena ja piirata lisaks võrgutasemel. Veebiserver vajab väljapoole tavaliselt vaid mõnda sihtkohta: paketiallikad, makse- ja saatmisteenuse pakkujad, meilirelee, teatud liidesed.
Väljamineva liikluse tulemüür aitab kahekordselt. See peatab SSRF-päringud sisevõrku ja raskendab pärast sissemurdmist, näiteks paigata PHP versiooni kaudu, täiendavate tööriistade järelelaadimist. Kuidas reegleid üles ehitada, kirjeldab Tulemüür veebiserverile: avage ainult vajalikud pordid. Millised ühendused server tegelikult loob, näitab Serveri väljaminevate ühenduste kontrollimine.
Pilvekeskkondades kuulub siia ka metaandmeteenuse kõvendatud variant. OWASP nimetab AWS-i jaoks üleminekut IMDSv2-le ja IMDSv1 väljalülitamist.
SSRF-i jälitamine olemasolevas koodis
Kiire sissepääs on otsing kohtadest, kus päringufunktsioonid saavad väärtusi päringust:
grep -rnE "(curl_init|file_get_contents|fopen|getimagesize|copy)\s*\(" src/ --include="*.php" | grep -E '\$_(GET|POST|REQUEST)|\$url'
grep -rn "CURLOPT_FOLLOWLOCATION" src/ --include="*.php"
Tabamused on kontrolliülesanded. Eriti põhjalikult peaksite vaatama funktsioone, mida kasutavad administraatorid: impordid, veebikonksude sätted, pistikprogrammide uuenduskontrollid.
Kergesti jäävad märkamata PDF-generaatorid, mis teisendavad HTML-i koos põimitud piltide või stiililehtedega dokumentideks. Kui osa sellest HTML-ist pärineb kasutaja sisendist, näiteks vabalt valitava logoga arvete puhul, pärib generaator teatud tingimustel aadresse, mille kasutaja määrab. Kontrollige seal kaugressursside laadimise sätteid ja lülitage see välja, kui seda ei vajata.
Kuidas PHP SOS konkreetselt aitab?
- Me leiame kõik kohad, kus teie rakendus aadresse pärib, ka pistikprogrammides ja teekides.
- Me ehitame keskse päringufunktsiooni lubatud nimekirja, protokollipiirangu ja IP-kontrolliga.
- Me määrame väljamineva liikluse reeglid ja kaitseme pilvekeskkondades metaandmeteenuseid.
- Me kontrollime elluviimist väljastpoolt ja dokumenteerime lubatud sihtkohad.
Teie rakenduse sõltumatu kontrolli kirjeldab Turvaaudit ja läbitungimistest.
Korduma kippuvad küsimused
Milliseid PHP funktsioone saab SSRF-iks kuritarvitada?
Kõiki, mis pärivad aadressi kasutaja sisendist: cURL, file_get_contents ja fopen URL-wrapperitega, pildi- ja XML-funktsioonid, mis laadivad kaugfaile, ning teegid veebikonksude, voogude või linkide eelvaadete jaoks.
Kas piisab sisemiste IP-aadresside blokeerimisest?
Üksi mitte. OWASP nimetab keelunimekirjad möödaminekuks altiks ja soovitab lubatud nimekirju. Lisaks peab rakendus kasutama täpselt seda aadressi, mida ta kontrollis, ega tohi ümbersuunamisi järgida.
Miks on SSRF pilves eriti kriitiline?
Pilveteenuse pakkujad teevad instantsidele kättesaadavaks sisemised metaandmeteenused, mille kaudu on osaliselt kättesaadavad ligipääsuandmed. Kui rakendus saab sinna päringuid saata, saab ründaja need andmed tema kaudu kätte. Pakkujad pakuvad nende teenuste kõvendatud variante, mis peaksid olema aktiveeritud.
Mida annab väljamineva liikluse tulemüür?
See piirab, milliseid sihtkohti server üldse kätte saab. Isegi kui koodi kontroll ebaõnnestub, jäävad sisesüsteemid siis kättesaamatuks. Lisaks raskendab see pärast sissemurdmist pahakoodi järelelaadimist ja andmete väljavoolu.