Kritinės web aplikacijų saugumo rizikos ir kaip jų išvengti

web aplikacijų saugumas

Visma Lietuva programinės įrangos saugumo komanda dirba su keliais šimtais įvairių produktų, naudojančių daugybę skirtingų technologijų. Dirbdami pastebime tam tikras su web aplikacijų saugumu susijusias tendencijas. Tekste aptarsime dažniausiai sutinkamus web aplikacijų pažeidžiamumus ir būdus, padedančius nuo jų apsisaugoti. 

Straipsnyje rašome apie Cross-site  Scripting pažeidžiamumą, nepakankamą prieigos kontrolę bei Cross-Site Request Forgery (CSRF). Visą informaciją lydės išsamūs pavyzdžiai su paaiškinimais. Šis straipsnis yra paremtas programinės įrangos saugumo specialisto bei OWASP Lithuania chapter lyderio Dominyko Šeikio mokymais „Internetinių puslapių saugumo pagrindai”. Minimi pažeidžiamumai mokymuose aptariami kur kas plačiau, taip pat kalbama apie įrankius, leidžiančius aptikti saugumo spragas bei programavimo principus, padėsiančius užtikrinti jūsų puslapio saugumą. Mokymuose taip pat daug praktinių užsiėmimų, kurie padės geriau suprasti ir įsisavinti teorinę medžiagą. 

Trys labiausiai paplitusios web aplikacijų saugumo spragos

Cross-site Scripting. 

Kas tai ir kodėl tai veikia?

Cross-site Scripting (XSS) yra saugumo spraga web aplikacijoje, leidžianti naudotojui įterpti HTML kodą iš kurio formuojamas dinaminis turinys. Pavyzdžiui, vykdant paiešką, rašant komentarus ar nurodant adresą. Naršyklės vienodai traktuoja HTML žymėjimą (markup) nepriklausomai ar jis buvo sugeneruotas back-end’o ar įterptas tinklalapio naudotojo, todėl jei tinklalapis leidžia naudotojui įterpti JavaScript kodą, naršyklė formuodama dinaminį HTML turinį jį įvykdys. Tokiu atveju, potencialus įsilaužėlis gali pasiekti slapukus, sesijos duomenis ar kitą slaptą informaciją, kurią saugo naršyklė. Šie script’ai netgi gali perrašyti HTML puslapio turinį ar inicijuoti pelės mygtukų paspaudimus. 

Kaip piktavalis gali įvykdyti išpuolį?

Priklausomai nuo XSS rūšies, piktavalis turi kelis variantus:

  • Pateikti phishing’o nuorodą, kurią paspaudus aukos naršyklėje bus vykdomas JavaScript kodas.
  • Palikti įrašą (komentarą ar žinutę) su įvestu JavaScript kodu, kuris bus išsaugomas duomenų bazėje. Aukai atsidarius puslapį, bus vykdomas JavaScript kodas. 

Kas gali būti pasiekta? 

  • Piktavalis gali perimti aukos naršyklės kontrolę: skaityti DOM elementus, manipuliuoti  naudotojo sąsaja ar nukreipti į savo kontroliuojamą puslapį. 
  • Gali įrašyti Keylogger ar kitas programėles, padedančias atskleisti asmeninius duomenis.
  • Gali perimti sesijos duomenis. 

Kaip to išvengti?

Contextual Output Encoding (kontekstinis išvesties kodavimas) gali būti naudojamas kaip pagrindinis gynybos mechanizmas XSS atakoms sustabdyti. Tai reiškia, jog pavojingus simbolius tokius kaip „<” ar “>” reiktų koduoti HTML esybėm (HTML entities), nepriklausomai kuriam kontekste (HTML, JavaScirpt, atributo ar CSS) nukeliauja naudojo įvesti duomenys. Tokiu būdu, naršyklė HTML esybes traktuos ne kaip HTML kodą ir jo nevykdys. Klientinės pusės framework’ai, tokie kaip Angular, ReactJS pagal nutylėjimą apsaugo nuo XSS atakų. Visgi, praktikoje matome, kad programuotojai nesuprasdami kaip naudojami tam tikri komponentai, padaro klaidų, sukuriančių saugumo spragas. Dažniausia klaida – neteisingas duomenų susiejimas (data binding). 

Pateiksime teisingo ir klaidingo kodo pavyzdžius: 

formuojamas dinaminis html turinys

Šiame pavyzdyje matome, jog parametro “name” naudotojo įvesta reikšmė vartojama formuojant dinaminį HTML turinį naudojant echo funkciją. Kadangi išvestis nėra koduojama, piktavaliui įvedus “<script>alert(1)</script>” naršyklė interpretuoja kaip JavaScript kodą ir bus įvykdytas alert pranešimas. 

pavojingi simboliai “”

Šiame pavyzdyje pavojingus simbolius  “<” ir “>” paverčiame HTML esybėmis, kurių naršyklė netraktuoja kaip HTML kodo, todėl JavaScript kodas nėra vykdomas. 

Padarykime testą. Kuris iš pateiktų knockout.js elementų susiejimo metodų turi saugumo spragą.

  1. <h2>Hello, <span data-bind=“text: fullName”> </span>!</h2>
  2. <h2>Hello, <span data-bind=“html: fullName”> </span>!</h2>

Kodas, turintis saugumo spragą yra tas, kuris atlieka duomenų susiejimą (data binding) kaip HTML. Viena iš sąlygų JavaScript kodui vykdyti – HTML aplinka. 

Kurį variantą pasirinkote jūs?

Broken Access Controls (Nepakankama prieigos kontrolė)

Nepakankama prieigos kontrolė dažniausiai reiškia programavimo klaidas, susijusias su autorizacija. Jas galima skirstyti į dvi kategorijas: 

  1. Nepakankamai gerai užtikrinta prieiga prie tam tikro objekto. Įsivaizduokite web aplikaciją, kuri generuoja jūsų sąskaitos faktūros užsakymą. Jai suteikiamas unikalus objekto ID. Šis objekto ID turėtų būti prieinamas tik jums, tačiau kartais nutinka, kad pekeitus ID numerį, žmogus gali pamatyti kažkieno kito sąskaitą faktūrą.  

Broken Access Controls

 

2. Nepakankamai apsaugota prieiga prie tam tikro funkcionalumo. Pavyzdžiui, paprastas web aplikacijos naudotojas gali kurti naujus naudotojus, nors pagal taisykles tai daryti turėtų tik administratorius. 

Kas gali būti pasiekta?

Šiais atvejais galima pažeisti duomenų integralumą bei konfidencialumą. 

Kaip to išvengti?

  • Nuodugniai patikrinkite prieigos kontrolę kiekvienai rolei ir dokumentuokite kiekvienos rolės prieigą prie tam tikrų išteklių.  
  • Nustatykite prieigos kontrolę iš mažiausiai teisių turinčio naudotojo perspektyvos.
  • Neleiskite niekam prisijungti pagal nutylėjimą. Taip kiekvienas veiksmas, kuris neturi aiškaus leidimo bus uždraustas.
  • Užregistruokite kiekvieną įvykį, kurį atliekant pasiekiami jautrūs duomenys. 

Svarbiausias žingsnis yra gerai apgalvoti aplikacijos prieigos kontrolės reikalavimus ir užfiksuoti juos saugumo politikoje. Primygtinai rekomenduojame naudoti prieigos kontrolės matricą, kad apibrėžtumėte prieigos kontrolės taisykles. Dokumente reikia apibrėžti, kokios naudotojų rolės gali prieiti prie sistemos, kokias funkcijas bei turinį kiekviena šių rolių gali pasiekti. Prieigos kontrolės mechanizmą reikia išsamiai testuoti, tam jog įsitikintumėte, kad nėra galimybės jo apeiti. Šiems testams reikia įvairių paskyrų ir daugybės bandymų pasiekti neteisėtą turinį ar funkcijas. Tam reikia sudaryti sąrašą naudotojų, kurie gali atlikti vieną ar kitą veiksmą ir kokius resursus naudotojas gali pasiekti atlikdamas konkretų veiksmą.

Cross-Site Request Forgery (CSRF)

A Cross-site Request Forgery (CSRF) arba vieno paspaudimo ataka (one – click – attack), yra paplitusi saugumo problema, kai iš aukos naršyklės jam nepastebint yra siunčiamos užklausos į svetainę prie kurios jis prisijungęs. CSRF ir XSS skiriasi tuo, kad CSRF nereikia užkrėsti patikimų puslapių, ji gali veikti iš nepatikimų puslapių dėl atviros web architektūros. Piktavalis turi būti įsitikinęs, kad auka yra prisijungusi (t.y. turi aktyvią sesiją),o siunčiami parametrai jam nuspėjami. 

Cross-Site Request Forgery

Šiame pavyzdyje matome kaip piktavalis aukai atsiunčia laišką su nuorodą, kurią paspaudęs mybank.com naudotojas, tuo metu turintis aktyvią sesiją, atlieka nepageidaujamus veiksmus. Nuoroda turi užprogramuotą veiksmą, o ją paspaudus, šis veiksmas bus atliktas be aukos žinios. 

Kas gali būti pasiekta? 

Visų pirma, duomenis galima pakeisti, atnaujinti arba ištrinti, tad yra pažeidžiamas duomenų vientisumas. Praktikoje dažnai išnaudojamas slaptažodžio keitimo funkcionalumas. Pagalvokite, jog dažnai visų naudotojų, nepriklausomai nuo jo rolės, slaptažodžio keitimo parametrai yra tokie patys. Dėl šios priežasties piktavaliui pakankamai nesudėtinga padirbti užklausą, o jei naujo slaptažodžio nustatymui nereikia įvesti senojo, piktavalis nesunkiai gali perimti aukos paskyrą.

Kaip to išvengti?

Web aplikacija naudotojui turėtų išduoti papildomą parametrą, kuris nebūtų nuspėjamas piktavaliui. Paprastai naudotojui yrai išduodamas unikalus CSRF žetonas (token), kuris turi būti validuojamas back-end’e su kiekviena duomenis keičiančia užklausa. 

Kuris pavyzdys yra blogas ir kodėl?

Turime du paskyros slaptažodžio keitimo pavyzdžius. Abiejuose naudojami CSRF žetonai, tačiau tik viename jie implementuoti teisingai. Kuriame?

Nr.1.

POST /Account/Changepassword.aspx HTTP/1.1

Host: weird-host.visma.com

User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:68.0) 

Accept: text/plain, */*

Accept-Language: en-US,en;q=0.5

Accept-Encoding: gzip, deflate

Content-Type: text/plain;charset=utf-8

CSRF-TOKEN: m9cL2NlV0xJSUNnPT0iLCJ2YWx1ZSI6InZvWGdoaHZqZ0Vrd

Content-Length: 56

Connection: close

Cookie: SessionId=GHrk7uhxLDbQutQa4Z3R8K09OEIRdZQh; 

NewPassword=abcefgh&VerifyNew=abcdefg

 

Nr.2.

POST /Account/Changepassword.aspx HTTP/1.1

Host: weird-host.visma.com

User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:68.0) 

Accept: text/plain, */*

Accept-Language: en-US,en;q=0.5

Accept-Encoding: gzip, deflate

Content-Type: text/plain;charset=utf-8

Content-Length: 56

Connection: close

Cookie: SessionId=GHrk7uhxLDbQutQa4Z3R8K09OEIRdZQh; CSRF-TOKEN= m9cL2NlV0xJSUNnPT0iLCJ2YWx1ZSI6InZvWGdoaHZqZ0Vrd

NewPassword=abcefgh&VerifyNew=abcdefg

Teisingai implementuotus žetonus matome pirmajame pavyzdyje. Antrame, CSRF apsaugos mechanizmas yra neefektyvus, nors CSRF žetonas nėra nuspėjamas, bet piktavaliui ir nebūtina jo žinoti, nes aukos naršyklė pati pridės šias reikšmes į slapuką, jei užklausa siunčiama į tą patį šaltinį (origin).

Pirmajame pavyzdyje CSRF žetonas yra pridedamas kaip papildomas HTTP antraštės laukas (custom header), jei serveris prieš priimdamas užklausą pirmiausiai patikrins šią reikšmę, piktavaliui šią ataką įvykdyti bus beveik neįmanoma.

Interneto puslapių saugumas

Šiame tekste aptarėme tik kelias OWASP kritines web aplikacijų saugumo rizikas. Programinės įrangos saugumo specialistas Dominykas Šeikis mokymuose „Internetinių puslapių saugumo pagrindai” daug plačiau aptaria kiekvieną minėtą saugumo spragą, mokymuose jis kalba ir apie SQL Injection techniką bei įrankius (tokius kaip Burp Free, Firefox Developer Tool (F12)), padėsiančius aptikti jūsų puslapio pažeidžiamumus prieš juos aptinkant piktavaliams. Mokymai taip pat turi praktinę dalį, kurios metu naudodami interception proxy, išmoksite surasti ir išnaudoti pažeidžiamumus mokomosiose programose. 

Daugiau apie mokymus.

 

4