Kas yra OWASP ir kodėl tai turėtų rūpėti kiekvienam programuotojui
Jei dirbate su web aplikacijomis, tikriausiai esate girdėję apie OWASP. Bet jei ne – tai laikas susipažinti. OWASP (Open Web Application Security Project) yra tarptautinė ne pelno organizacija, kuri jau daugiau nei 20 metų padeda programuotojams kurti saugesnes aplikacijas. Jų garsiausia iniciatyva – OWASP Top 10 sąrašas, kuris kas kelerius metus atnaujinamas ir parodo dažniausias bei pavojingiausias saugumo spragas web aplikacijose.
Paskutinis atnaujinimas įvyko 2021 metais, ir nors kai kurie punktai išliko tie patys, pastebimi įdomūs pokyčiai – pavyzdžiui, atsirado naujos kategorijos, susijusios su programinės įrangos tiekimo grandinės saugumu ir serverio konfigūracijos klaidomis. Tai rodo, kad kibernetinių grėsmių kraštovaizdis nuolat keičiasi.
Injection atakos: kai vartotojo įvestis tampa ginklu
Injection tipo atakos – tai klasika, kuri vis dar išlieka viena didžiausių problemų. Principas paprastas: užpuolikas įterpia kenkėjišką kodą į jūsų aplikacijos įvesties laukus, tikėdamasis, kad sistema jį vykdys. SQL injection yra populiariausias pavyzdys.
Įsivaizduokite prisijungimo formą, kur vartotojas įveda savo el. paštą ir slaptažodį. Jei programuotojas tiesiog įklijuoja šias reikšmes į SQL užklausą be jokio filtravimo, užpuolikas gali įvesti kažką panašaus į ' OR '1'='1 ir gauti prieigą prie sistemos. Skamba banaliai, bet tikrovėje tokių spragų vis dar randama net didelėse kompanijose.
Kaip apsisaugoti? Pirma, niekada nenaudokite string concatenation SQL užklausoms kurti. Naudokite prepared statements arba ORM bibliotekas, kurios automatiškai apdoroja įvestį. Antra, validuokite ir sanitizuokite visą vartotojo įvestį – ir frontend’e, ir backend’e. Trečia, taikykite least privilege principą duomenų bazėje – aplikacijos vartotojas neturėtų turėti DROP TABLE teisių.
Injection problema apima ne tik SQL – tai gali būti NoSQL injection, OS command injection, LDAP injection ir kiti variantai. Esmė ta pati: niekada nepasitikėkite vartotojo įvestimi.
Autentifikacijos ir sesijų valdymo problemos
Autentifikacija atrodo paprasta – vartotojas įveda slaptažodį, sistema patikrina, ar jis teisingas, ir suteikia prieigą. Bet praktikoje čia slypi daugybė spąstų, į kuriuos programuotojai įkrenta.
Viena dažniausių klaidų – silpnas slaptažodžių saugojimas. Jei vis dar saugote slaptažodžius plain text formatu arba naudojate MD5 – sustokite ir viską perrašykite. Šiuolaikinės aplikacijos turi naudoti bcrypt, Argon2 arba panašius algoritmus, specialiai sukurtus slaptažodžiams hash’inti. Šie algoritmai yra lėti tyčia – tai apsunkina brute force atakas.
Sesijų valdymas – kita problema. Session ID turi būti pakankamai ilgas ir atsitiktinis, kad jo nebūtų galima atspėti. Po sėkmingo prisijungimo turėtų būti generuojamas naujas session ID (session fixation apsauga). Sesijos turi turėti timeout’ą. Ir, žinoma, session ID niekada neturėtų keliauti URL parametruose – tik saugiuose cookies su HttpOnly ir Secure flag’ais.
Dar vienas aspektas – daugiafaktorė autentifikacija (MFA). 2024 metais tai jau nebeturėtų būti premium funkcija – tai turėtų būti standartas, bent jau administratoriams ir privilegijuotiems vartotojams. SMS kodai nėra idealus sprendimas (SIM swapping atakos), bet geriau nei nieko. Authenticator aplikacijos ar hardware token’ai yra geresnis pasirinkimas.
Jautrių duomenų atskleidimas
Duomenų nutekėjimai – tai košmaras bet kuriai kompanijai. Ir dažnai problema ne tiek išoriniai užpuolikai, kiek paprasta aplaidumas.
Pirmiausia – šifravimas. Visi jautrūs duomenys turi būti šifruojami ir transit (HTTPS visur!), ir at rest (duomenų bazėje). Bet čia yra niuansų. HTTPS sertifikatas pats savaime neužtikrina saugumo, jei naudojate pasenusias TLS versijas ar silpnus cipher suite’us. Patikrinkite savo konfigūraciją su įrankiais kaip SSL Labs.
Duomenų bazėje saugomi jautrūs duomenys – kreditinių kortelių numeriai, asmens kodai, sveikatos informacija – turėtų būti šifruojami atskirai, naudojant tinkamus key management procesus. Ir ne, šifravimo rakto saugojimas tame pačiame serveryje kaip duomenų bazė nėra gera idėja.
Kita dažna problema – per daug informacijos error pranešimuose. Stack trace’ai production aplinkoje neturėtų būti rodomi vartotojams. Jie suteikia vertingos informacijos potencialiems užpuolikams apie jūsų sistemos architektūrą, naudojamas bibliotekas ir galimas spragas.
Nepamirškite ir apie duomenų minimizaciją. Ar tikrai reikia saugoti visą kreditinės kortelės numerį? Gal užtenka paskutinių keturių skaitmenų? Ar reikia saugoti vartotojų duomenis amžinai? GDPR ir kiti reguliavimai skatina saugoti tik tai, kas būtina, ir tik tiek laiko, kiek reikia.
XML External Entities (XXE) ir kitos parsing problemos
XXE atakos galbūt nėra tokios žinomos kaip SQL injection, bet jos gali būti lygiai taip pat pavojingos. Problema atsiranda, kai aplikacija apdoroja XML įvestį nenustačiusi tinkamų apribojimų.
Užpuolikas gali įterpti specialiai suformuotą XML, kuris nurodo sistemą įkelti išorinius failus arba net atlikti SSRF (Server-Side Request Forgery) atakas. Pavyzdžiui, gali būti nuskaitomas /etc/passwd failas arba atliktos užklausos į vidinius tinklo resursus.
Sprendimas? Išjunkite external entities apdorojimą XML parser’iuose. Dauguma šiuolaikinių bibliotekų leidžia tai padaryti per konfigūraciją. Dar geriau – jei galite, naudokite JSON vietoj XML. Jis paprastesnis ir turi mažiau saugumo spąstų.
Panašios problemos gali kilti ir su kitais parser’iais – YAML, serialization bibliotekos ir pan. Bendras principas: būkite atsargūs su bet kokiu sudėtingu formatu, kuris leidžia vykdyti kodą ar įkelti išorinius resursus.
Broken Access Control: kai vartotojai mato tai, ko neturėtų
Access control problemos 2021 metų OWASP Top 10 sąraše pakilo į pirmą vietą – ir tai nenuostabu. Tai viena dažniausių ir pavojingiausių spragų.
Klasikinis pavyzdys: jūsų aplikacijoje vartotojas gali peržiūrėti savo užsakymą URL /orders/12345. Kas nutiks, jei jis pakeis skaičių į /orders/12346? Ar sistema patikrina, ar tas užsakymas tikrai priklauso jam? Jei ne – sveiki atvykę į IDOR (Insecure Direct Object Reference) pasaulį.
Kita problema – funkcijų prieigos kontrolė. Pavyzdžiui, administratoriaus funkcijos pasiekiamos per /admin/users, bet niekas netikrina, ar vartotojas tikrai turi admin teises. Užpuolikas tiesiog atspėja URL ir gauna pilną prieigą.
Kaip taisyti? Visada tikrinkite prieigos teises server side. Frontend’o apribojimai (paslėpti mygtukai, disabled laukai) yra tik UX patobulinimas, ne saugumo priemonė. Kiekvienas API endpoint turi validuoti, ar dabartinis vartotojas turi teisę atlikti prašomą veiksmą su konkrečiu resursu.
Naudokite role-based arba attribute-based access control sistemas. Dokumentuokite, kas turi prieigą prie ko. Reguliariai audit’inkite prieigos teises – dažnai pasitaiko, kad vartotojai išeina iš kompanijos, bet jų paskyros lieka aktyvios su visomis teisėmis.
Security Misconfiguration: kai numatytieji nustatymai tampa priešu
Daugelis saugumo incidentų įvyksta ne dėl sudėtingų exploit’ų, o dėl paprasčiausio nesukonfigūravimo. Paliekate default slaptažodį? Užmirštate išjungti debug režimą production’e? Neupdate’inate bibliotekų? Sveiki, tapote lengva auka.
Default kredencialai – tai absurdas, bet vis dar pasitaikantis. Admin/admin, root/root – jei jūsų sistemoje yra tokių paskyrų, užpuolikui nereikia būti genijumi. Pirmą kartą paleidus sistemą, turėtų būti privaloma pakeisti default slaptažodžius.
Debug režimas production aplinkoje – kita dažna klaida. Jis rodo detalią informaciją apie klaidų, atidaro papildomus endpoint’us, kartais net leidžia vykdyti kodą. Visada turėkite atskirą konfigūraciją development ir production aplinkoms.
Nereikalingos funkcijos ir servisai taip pat kelia riziką. Jei nenaudojate FTP, išjunkite jį. Jei nereikia tam tikro API endpoint’o – pašalinkite. Kiekviena papildoma funkcija – tai papildoma atakos paviršiaus dalis.
Security headers – paprasta, bet efektyvi apsauga. Content-Security-Policy, X-Frame-Options, Strict-Transport-Security – šie HTTP headeriai gali apsaugoti nuo daugelio atakų. Ir jų įdiegimas užtrunka vos kelias minutes.
Kas toliau: kaip integruoti saugumą į kasdienį darbą
OWASP Top 10 žinojimas – tai puiku, bet teorija be praktikos neturi prasmės. Saugumas neturėtų būti „kažkas, ką padarysime vėliau” – jis turi būti integruotas į visą development procesą.
Pradėkite nuo code review. Kai peržiūrite kolegos kodą, žiūrėkite ne tik į funkcionalumą, bet ir į saugumą. Ar validuojama įvestis? Ar teisingai valdomas autentifikacija? Ar nėra hardcoded slaptažodžių? Padarykite saugumo klausimus dalimi jūsų review checklist’o.
Automatizuokite, kur galite. SAST (Static Application Security Testing) įrankiai gali rasti daugelį problemų dar prieš kodui patenkant į production. DAST (Dynamic Application Security Testing) įrankiai testuoja veikiančią aplikaciją. Dependency checkers perspėja apie žinomas spragas naudojamose bibliotekose. Integruokite šiuos įrankius į CI/CD pipeline’ą.
Mokykitės iš kitų klaidų. Skaitykite apie security breach’us, analizuokite, kas nutiko ir kaip to išvengti. Dalyvaukite security konferencijose ar bent žiūrėkite jų įrašus. Bug bounty platformos kaip HackerOne ar Bugcrowd gali būti puikus būdas gauti išorinį vertinimą.
Ir svarbiausia – kurkite saugumo kultūrą komandoje. Saugumas nėra vien security team’o atsakomybė – tai kiekvieno programuotojo, testuotojo, DevOps inžinieriaus darbas. Kai saugumas tampa natūralia darbo dalimi, o ne papildoma našta, rezultatai būna gerokai geresni. OWASP Top 10 – tai ne baubas, kurio reikia bijoti, o vadovas, padedantis kurti geresnes, saugesnes aplikacijas. Ir tai tikrai verta investuoto laiko.
