Kas tai per žvėris – path traversal?
Kai kurie saugumo pažeidimai skamba baisiai sudėtingai, bet iš tikrųjų veikia pagal paprastą principą. Path traversal (arba directory traversal, directory climbing) yra būtent toks atvejis. Įsivaizduokite, kad jūsų svetainė turi galeriją, kur vartotojai gali peržiūrėti nuotraukas. URL gali atrodyti taip: example.com/gallery?image=vacation.jpg. Viskas gerai, kol kažkas nepakeičia to parametro į ../../../../etc/passwd.
Štai ir visa esmė – užpuolikas bando „užlipti” per katalogų struktūrą aukštyn ir pasiekti failus, kurių neturėtų matyti. Tie ../ simboliai reiškia „eik vienu katalogu aukščiau”. Pakartojus juos kelis kartus, galima išlipti iš numatyto katalogo ir pradėti naršyti po visą serverio failų sistemą.
Problema ta, kad daugelis programuotojų tiesiog paima vartotojo įvestą reikšmę ir nukopijuoja ją tiesiai į failų sistemos operacijas. Jokios validacijos, jokių patikrinimų. Serveris paklusniai vykdo komandą ir grąžina failą, kurio niekas neturėtų matyti – slaptažodžių hešus, konfigūracijos failus su duomenų bazės prisijungimais, programinio kodo fragmentus.
Kaip tai veikia praktikoje
Paimkime realų pavyzdį. Turite PHP aplikaciją, kuri rodo dokumentus:
$file = $_GET['doc'];
include('/var/www/docs/' . $file);
Atrodytų, kad viskas saugiai – juk mes pridedame /var/www/docs/ priekyje, tai vartotojas gali pasiekti tik tuos failus, kurie yra tame kataloge, tiesa? Ne visai. Jei užpuolikas paduos tokį parametrą: ../../../../etc/passwd, gauname:
/var/www/docs/../../../../etc/passwd
Operacinė sistema šitą kelią supaprastina ir gauname tiesiog /etc/passwd. Bum, saugumo skylė. Užpuolikas dabar mato visų sistemos vartotojų sąrašą.
Bet tai tik pradžia. Priklausomai nuo serverio konfigūracijos ir programos teisių, galima pasiekti:
– Konfigūracijos failus su duomenų bazės slaptažodžiais
– Aplikacijos išeities kodą
– Logų failus su jautria informacija
– Kitus vartotojų įkeltus failus
– SSH raktus
– Sesijų failus
Windows sistemose path traversal atrodo šiek tiek kitaip – naudojami ..\ simboliai vietoj ../, bet principas tas pats. Be to, Windows turi įdomią ypatybę – galima naudoti absoliučius kelius su diskų raidėmis: C:\Windows\System32\drivers\etc\hosts.
Kodavimo triukai ir apejimai
Dabar įdomiausia dalis. Daugelis programuotojų, sužinoję apie path traversal, pamano: „Gerai, tiesiog išfiltruosiu ../ sekas!” Ir prideda kažką panašaus:
$file = str_replace('../', '', $_GET['doc']);
Problema ta, kad užpuolikai nėra kvaili. Jie žino visokių triukų, kaip apeidinėti tokius primityvius filtrus:
URL kodavimas: Vietoj ../ galima naudoti %2e%2e%2f. Daugelis serverių automatiškai dekoduoja URL parametrus, todėl filtras nemato problemos, bet failų sistema gauna tą patį rezultatą.
Dvigubas kodavimas: Dar įdomiau – %252e%252e%252f. Čia procentas pats yra užkoduotas. Kai kurios aplikacijos dekoduoja du kartus.
Unicode/UTF-8 triukai: Simboliai ..%c0%af arba ..%ef%bc%8f gali būti interpretuojami kaip ../ po normalizacijos.
Mišrios pasvirųjų: Windows priima abi pasvirąsias – ..\ ir ../. Galima maišyti: ..\/ arba ..\../.
Pertekliniai simboliai: ....// arba ..;/ kai kuriose sistemose veikia.
Absoliutūs keliai: Kartais galima tiesiog nurodyti pilną kelią: /etc/passwd arba C:\boot.ini.
Yra buvę atvejų, kai saugumo tyrėjai rasdavo pažeidžiamumų net gerai žinomose sistemose, nes filtrai neapsaugojo nuo visų šių variantų. Tai primena žaidimą „katė ir pelė” – kūrėjai prideda naujų filtrų, užpuolikai sugalvoja naujų apeijimo būdų.
Realūs incidentai ir jų pasekmės
Path traversal nėra tik teorinė grėsmė. 2019 metais buvo rasta kritinė path traversal pažeidžiamybė populiariame Atlassian Jira produkte. Užpuolikai galėjo pasiekti bet kokius failus serveryje, įskaitant konfigūracijos failus su duomenų bazės kredencialais. Tūkstančiai įmonių turėjo skubiai atnaujinti sistemas.
Panašiai 2020-aisiais Citrix Application Delivery Controller turėjo path traversal pažeidžiamumą, kuris leido nesertifikuotiems vartotojams skaityti bet kokius failus iš sistemos. Tai buvo masiškai išnaudojama, nes Citrix produktai naudojami daugelyje stambių organizacijų.
Bet ne tik didžiosios korporacijos kenčia. Mažesnės įmonės dažnai naudoja custom sprendimus arba mažiau žinomus open-source projektus, kurie gali turėti tokių pažeidžiamumų. Ir būtent jie dažnai tampa taikiniais, nes neturi dedikuotų saugumo komandų.
Vienas įdomus atvejis buvo su WordPress įskiepiu, kuris leido vartotojams atsisiųsti savo duomenis. Kūrėjai nenormalizavo failų kelių, todėl buvo galima atsisiųsti wp-config.php failą su visais duomenų bazės prisijungimais. Įskiepis buvo įdiegtas dešimtyse tūkstančių svetainių.
Kaip tinkamai apsisaugoti
Gerai, užtenka bauginimo. Kaip iš tikrųjų apsisaugoti nuo path traversal atakų? Štai konkretūs patarimai, kuriuos galite įgyvendinti jau šiandien:
1. Niekada nedarykite tiesioginio vartotojo įvesties mapping į failų kelius
Vietoj to naudokite whitelist požiūrį. Jei turite galeriją su nuotraukomis, sukurkite masyvą leidžiamų failų:
$allowed_files = ['vacation.jpg', 'beach.jpg', 'mountains.jpg'];
$file = $_GET['image'];
if (in_array($file, $allowed_files)) {
// Saugiai rodyti failą
}
2. Naudokite ID vietoj failų vardų
Užuot leidę vartotojui nurodyti failą tiesiogiai, naudokite duomenų bazę:
$file_id = intval($_GET['id']);
$file_info = $db->query("SELECT filename FROM files WHERE id = ?", [$file_id]);
Taip vartotojas niekada nežino tikrojo failo vardo ar vietos.
3. Validuokite ir normalizuokite kelius
Daugelis programavimo kalbų turi įrankius kelių normalizavimui:
PHP: realpath() funkcija išsprendžia visus ../ ir grąžina absoliutų kelią. Tada galite patikrinti, ar jis prasideda leistinu katalogu.
Python: os.path.normpath() ir os.path.abspath()
Node.js: path.normalize() ir path.resolve()
4. Apribokite failų sistemos prieigą
Jūsų web aplikacija neturėtų veikti su root teisėmis. Sukurkite atskirą vartotoją su minimaliomis teisėmis. Naudokite chroot arba konteinerius (Docker), kad izoliuotumėte aplikaciją.
5. Naudokite framework’ų saugumo funkcijas
Modernūs framework’ai dažnai turi įtaisytas apsaugas. Laravel turi Storage fasadą, Django – FileSystemStorage, Express.js – express.static su tinkamomis parinktimis. Nenaudokite žemo lygio failų operacijų, jei galite to išvengti.
Testavimas ir aptikimas
Kaip sužinoti, ar jūsų aplikacija pažeidžiama? Štai keletas būdų:
Rankinis testavimas: Pabandykite įvesti ../ sekas į bet kokius URL parametrus, kurie atrodo susiję su failais. Stebėkite serverio atsakymus – ar gaunate klaidas, ar netikėtą turinį?
Automatizuoti įrankiai: Burp Suite, OWASP ZAP, Nikto – visi šie įrankiai turi path traversal tikrinimo modulius. Jie automatiškai bando šimtus skirtingų payload’ų ir variantų.
Kodo peržiūra: Ieškokite vietų, kur vartotojo įvestis naudojama failų operacijose:
– file_get_contents(), fopen(), include(), require() PHP
– open(), os.path.join() Python
– fs.readFile(), fs.createReadStream() Node.js
Penetracijos testavimas: Jei kuriate rimtą aplikaciją, verta pasamdyti profesionalus saugumo tyrėjus. Jie ras ne tik path traversal, bet ir kitas pažeidžiamybes.
Įdomus faktas – daugelis path traversal pažeidžiamumų randama ne pačioje aplikacijoje, o trečiųjų šalių bibliotekose ar įskiepiuose. Todėl svarbu reguliariai atnaujinti visas priklausomybes ir sekti saugumo pranešimus.
Web Application Firewall ir kitos gynybos linijos
Netgi su geriausiu kodu, verta turėti papildomų apsaugos sluoksnių. Web Application Firewall (WAF) gali aptikti ir blokuoti path traversal bandymus dar prieš jiems pasiekiant jūsų aplikaciją.
ModSecurity yra populiarus open-source WAF su OWASP Core Rule Set (CRS), kuris turi taisykles path traversal aptikimui. Cloudflare, AWS WAF, Azure WAF – visi jie siūlo panašias funkcijas.
Bet WAF nėra sidabrinė kulka. Jis gali duoti false positives (blokuoti teisėtus užklausimus) arba false negatives (praleisti atakas). Tai turėtų būti papildoma apsauga, ne vienintelė.
Kitos naudingos apsaugos priemonės:
Intrusion Detection Systems (IDS): Snort, Suricata gali stebėti tinklo srautą ir aptikti įtartinus šablonus.
File Integrity Monitoring: Įrankiai kaip OSSEC ar Tripwire stebi, ar nesikeitė svarbūs sistemos failai. Jei užpuolikas vis tik prasiskverbtų, tai padėtų greitai aptikti.
Logging ir monitoring: Loginkite visas failų prieigos operacijas. Jei matote daug 404 klaidų su ../ sekose, tai aiškus atakos požymis.
Ką daryti, jei aptikote pažeidžiamumą
Tarkime, radote path traversal pažeidžiamumą savo sistemoje. Nepanikuokite, bet veikite greitai:
Pirmas žingsnis – įvertinkite mastą: Ar tai production aplinkoje? Ar pažeidžiamumas jau buvo išnaudotas? Patikrinkite logus – ieškokite įtartinų užklausimų su ../, %2e%2e ir panašiai.
Antras žingsnis – laikinai pašalinkite riziką: Jei įmanoma, laikinai išjunkite pažeidžiamą funkciją. Arba pridėkite griežtą input validaciją kaip greitą patch’ą (bet ne kaip galutinį sprendimą).
Trečias žingsnis – ištaisykite teisingai: Implementuokite vieną iš aukščiau aprašytų sprendimų. Whitelist požiūris arba ID-based sistema paprastai yra geriausi pasirinkimai.
Ketvirtas žingsnis – testuokite: Įsitikinkite, kad pataisymas veikia ir nesulaužė kitų funkcijų. Bandykite visus žinomus apeijimo būdus.
Penktas žingsnis – deploy’inkite ir stebėkite: Po pataisymo deployment’o, atidžiai stebėkite logus. Ar atakomis bandoma toliau? Ar nėra naujų klaidų?
Jei tai yra produktas, kurį naudoja kiti, turite informuoti vartotojus. Responsible disclosure principas – pirmiausia pataisykite, tada pranešite. Nedelsiant skelbti apie pažeidžiamumą prieš pataisymą tik pakenkia visiems.
Kas toliau: saugumo kultūra ir nuolatinis budėjimas
Path traversal yra tik viena iš daugelio galimų saugumo problemų. SQL injection, XSS, CSRF, authentication bypass – sąrašas ilgas. Bet visi jie turi bendrą vardiklį – kyla iš nepasitikėjimo vartotojo įvestimi.
Svarbiausias dalykas, kurį galite padaryti – ugdyti saugumo kultūrą savo komandoje. Tai reiškia:
Reguliarius code review, kur saugumo aspektai yra prioritetas. Automatizuotus testus, kurie tikrina pažeidžiamumus. Security training programuotojams – ne kartą per metus, o nuolat. Threat modeling naujoms funkcijoms – pagalvokite apie saugumą dar prieš rašydami kodą.
Naudokite SAST (Static Application Security Testing) įrankius savo CI/CD pipeline’e. SonarQube, Checkmarx, Veracode – jie gali automatiškai aptikti daugelį pažeidžiamumų dar prieš kodui patenkant į production.
Sekite saugumo naujienas ir CVE (Common Vulnerabilities and Exposures) pranešimus. Jei naudojate populiarias bibliotekas ar framework’us, užsiprenumeruokite jų security mailing lists.
Ir svarbiausia – priimkite, kad tobulos saugumo nėra. Visada bus naujų atakos vektorių, naujų pažeidžiamumų. Tai ne vienkartinis projektas, o nuolatinis procesas. Bet su tinkamomis praktikomis, įrankiais ir požiūriu, galite žymiai sumažinti riziką ir užtikrinti, kad path traversal ir panašios atakos nesugriaustų jūsų sistemos.
