Kaklemine turvalisusega

Meil avanes võimalus parandada kliendi veebirakenduses paar turvalisusega seotud probleemi. Selles postituses jagan mõtteid taoliste probleemide osas, kuidas me need parandasime ja kuidas sarnaseid vigu vältida.

20.10.2020 (3 minuti jagu lugemist)

Oleme aidanud Coop Eesti Keskühistul hallata ja arendada nende e-poe veebirakendust. 2020. aasta augustis jõudis meie lauale ülesanne parandada üks välise turvaeksperdi Ando Roots poolt raporteeritud veebirakenduses olev turvalisusega seotud probleem. Ta kirjutas sellest probleemist päris pika ja detailse artikli ka oma blogis.

Probleemi kirjeldus

Probleemi olemus oli iseenesest päris lihtne - see võimaldas ründajal koostada internetiaadressi, millele navigeerides oleks saanud varastada Coop'i veebirakendust kasutava isiku kasutajanime ja parooli või võtta üle tema sisse logitud sessioon. Nagu ka Ando oma blogis kirjutas, siis on sellised probleemid isegi aastal 2020 väga levinud, kuigi paljud raamistikud/teegid üritavad teha endast kõik, et tarkvaraarendajad ei teeks selliseid vigu. Sellele vaatamata peaksid kõik tarkvaraarendajad alati koodi kirjutades mõtlema ka võimalike ründevektorite peale. Kõige parem on seda teha nii, et tuleb panna end ründaja kingadesse juba koodi kirjutamise ajal. Ando poolt raporteeritud turvalisuse probleemid ei oleks näinud päevavalgust juhul kui eelmised Coop'i tarkvaraarenduse partnerid oleks pööranud ekstra tähelepanu kirjutatud koodile. Saabus meie kord mõelda kui ründajad! Panime enda valged mütsid pähe ja asusime koodi parandama.

Tehnilisem probleemi kirjeldus

Koodis eksisteerib võimalus seadistada internetiaadress, kuhu suunatakse peale edukat sisse logimist Coop'i e-poe veebirakendusse. See on üpris tavapärane funktsionaalsus, kuna loob võimaluse navigeerida autentimist vajavatele aadressidele, kuvada seal sisse logimise vormi ning suunata tagasi aadressile, kuhu üritati esialgu minna. Halva UX-iga veebirakendused kuvavad peale sisse logimist alati esilehte või mingisugust teist vaikimisi lehte unustades ära aadressi, kuhu üritati sisse logimata navigeerida. URL, kuhu suunatakse peale edukat sisse logimist antakse kaasa login vormi aadressile GET päringu parameetrina nimega next. Näiteks URL https://ecoop.ee/et/logisisse/?next=%2Fet%2Fostunimekirjad%2F suunab kasutaja peale sisse logimist tema ostunimekirjade vaatesse. Kui selline funktsionaalsus eksisteerib, siis on alati väga oluline kontrollida selle parameetri väärtust. Kui seda ei tehta, siis ründaja saab anda enda koostatud väärtuse, mis võib tekitada probleeme. Näiteks võib ründaja anda lingi https://ecoop.ee/et/logisisse/?next=https%3A%2F%2Fattack-site.com, mis peale edukat sisse logimist suunaks kasutaja ründaja kontrolli all olevale aadressile https://attack-site.com. Ründaja saab seal näiteks kuvada täpselt samasugust sisse logimise vormi nagu Coop'i enda vorm koos veateatega "Vale kasutajanimi või parool". Pahaaimamatu kasutaja arvaks, et tegi vea kasutajanime või parooli sisestamisel ning sisestaks need uuesti ründaja kontrolli all olevale vormile. Peale seda ründaja suunaks kasutaja tagasi päris Coop'i veebirakendusele, kus kasutaja oleks sisse logitud. Sellega koos oleks aga ründaja valduses ka kehtiv kasutajanimi ja parool. See on selles mõttes ideaalne rünnak, et kasutaja isegi ei pruugi märgata, et vahepeal andis oma kasutajanime ja parooli ründajale. On ainult aja küsimus, millal ründaja talle saadetud infoga midagi korda saadab.

Lahendus

Nagu eelmises paragrahvis mainisin, siis selle näiliselt lihtsa probleemi lahendamiseks on vaja ainult valideerida suunatava aadressi parameetri väärtust. Selleks on mitmeid erinevaid viise ja need sõltuvad veebirakenduse ülesehitusest. Meie otsustasime kirjutada lihtsa koodi, kus on kirjas kõik lubatud URL'id (alati koosta lubatud parameetrite nimekiri, mitte keelatud parameetrite nimekiri!). Teisisõnu, kui URL ei ole meie koodis defineeritud, siis ei ole ka lubatud sellise parameetri väärtus. Kui parameetri väärtus ei ole lubatud, siis kuvatakse kasutajale veateadet. Nii lihtne ongi. Ei hakka spetsiifilisi koodi näiteid siia tooma, sest see oleks erinev igas projektis (kui siiski pakub väga huvi, siis loe Ando kirjutatud artiklit).

Kokkuvõte

Kahjuks ei pöörata väga tihti tähelepanu turvalisusele enne intsidendi juhtumist. Seekord õnneks juhtus nii, et väline turvaekspert leidis selle probleemi ja andis teada Coop'ile ilma kurjasti ära kasutamata. On kahetsusväärne, et probleemi lahendamine raporteerimise hetkest võttis nii kaua aega, aga vähemalt sai see ikkagi lahendatud. Kui oled tarkvaraarendaja, siis ei tohi mitte kunagi usaldada sisendit, mis tuleb kasutajalt, sest kunagi ei tea, mil keegi koostab sellise sisendi, millega sinu kood ei oska arvestada. Alati mõtle nagu ründaja, et selliseid probleeme juba eos vältida.


Solutional on agiilne tarkvaraarenduse ettevõte professionaalsete inseneridega, kes suudavad lahendada tarkvaralised probleemid algusest lõpuni ilma vahendajateta.

Kirjuta meile e-post aadressile info@solutional.ee juhul kui vajad abi uute või olemasolevate projektide eduka teostusega.