Sadržaj

Cross Site Request Forgery napadi

Sažetak

CSRF napadi vrsta su mrežnih napada u kojima napadač zloupotrebom HTTP protokola i implementacija web preglednika nastoji postići da žrtva koristeći svoj web preglednik podnese HTML formu bez vlastite privole, a često i bez znanja da je forma uopće podnesena. U ovom radu obrađeno je funkcioniranje HTTP kolačića i HTML formi, koji su preduvjet za CSRF napade. Opisana je glavna ideja i tijek CSRF napada, kao i dvije varijante izvođenja, ovisno o vrsti HTML forme. Objašnjena je zaštita od CSRF napada, kao i dva najčešća pristupa njenoj implementaciji.

Uvod

Ispunjavanje formi (formulara) često je korištena funkcionalnost web preglednika. Primjerice svaki puta kada se korisnik prijavljuje u web stranicu on popunjava formu. HTML forme koriste se i za ostale namjene, a neke od njih su i monetarne prirode, primjerice ispunjavanje forme na stranici banke u cilju uplate na drugi bankovni račun. CSRF (engl. Cross-Site Request Forgery) napadi koriste se kako bi žrtva bez privole/znanja ispunila i poslala HTML formu. Bitan aspekt CSRF napada su HTML forme i način na koji se one prenose sa klijenta na poslužitelj. Jednako bitan aspekt je i autentifikacija korisnika (u kontekstu napada: žrtve), koja se najčešće implementira korištenjem kolačića, čija je funkcionalnost objašnjena u idućem poglavlju.

Osnove HTTP kolačića (engl. cookies)

Protokol HTTP u svojim inicijalnim verzijama nije imao nikakvu mogućnost pohrane stanja (engl. stateless), odnosno svi klijentski zahtjevi na poslužitelju su se obrađivali anonimno, pri čemu poslužitelj nije mogao odrediti identitet korisnika koji je uputio pojedini zahtjev [1]. Vrlo brzo je razvojem weba došlo do potrebe za identifikacijom pojedinih korisnika, primarno u cilju pružanja bolje usluge korisniku (pamćenje upisanih podataka u formama, personalizirane poruke korisniku i slično).

Kolačići (engl. cookies) najkorištenija su metoda identifikacije korisnika. Razvijeni su u kompaniji Netscape, a njihovo korištenje ubrzo je standardizirano i implementirano od strane svih većih web preglednika.

Kolačići su implementirani koristeći zaglavlja, odnosno postojeću infrastukturu protokola HTTP. Nakon što poslužitelj korištenjem posebnog zaglavlja Set-cookie klijentu dojavi potrebu za spremanjem kolačića, klijent (najčešće web preglednik) sadržaj kolačića sprema na računalo. U svakom idućem zahtjevu koji klijent upućuje prema poslužitelju, klijent će u posebno zaglavlje Cookie zapisati vrijednost kolačića koju je poslužitelj postavio. Same vrijednosti kolačića su parovi ključ-vrijednost, separarani točka zarezima, primjerice: ime=“ivan”;prezime=“horvat”. Slika 1 prikazuje postavljanje i korištenje kolačića.

 Slika 1: postavljanje kolačića

Prvi zahtjev, prikazan u slučaju A, prikazuje klijenta koji šalje zahtjev na poslužitelj “www.joes-hardware.com”, pri čemu klijent nikada prije nije pristupio navedenom poslužitelju i nema lokalno pohranjene kolačiće navedenog poslužitelja.

U obradi navedenog zahtjeva poslužitelj odgovara s odgovorom prikazanom u slučaju B, pri čemu poslužitelj prepoznaje nedostajanje Cookie zaglavlja u zahtjevu prikazanom u slučaju A, te u zaglavlju odgovora klijentu postavlja kolačić korištenjem Set-cookie zaglavlja. Sam kolačić pohranjuje samo dva para vrijednosti ključeva, pri čemu se ključ id postavlja na vrijednost “34294” a ključ domain se postavlja na vrijednost “joes-hardware.com”. Ključ domain posebno se interpretira od strane klijenta, o čemu će više riječi biti kasnije.

Na poslijetku, u slučaju C prikazan je idući zahtjev koji klijent upućuje prema istom poslužitelju, ali ovaj puta je prisutno zaglavlje Cookie, te je u njega upisan sadržaj kolačića, odnosno navedeni par ključ-vrijednost.

Konfiguracija kolačića

Poslužitelj može konfigurirati razne parametre vezane uz funkcionalnost kolačića korištenjem specijalnih ključeva u kolačiću. Nazivi tih specijalnih ključeva su: Expires, Domain, Path, i Secure.

Korištenjem ključa Domain moguće je klijentu dojaviti da sadržaj kolačića šalje i na specifične (ili sve) ddomene poslužitelja koji je postavio kolačić.

Ključ Path dojavljuje klijentu da sadržaj kolačića šalje samo ako putanja do resursa u URL-u započinje sa vrijednosti zapisanoj u ključu Path.

Ključ Expires klijentu dojavljuje kada kolačić prestaje biti validan, odnosno trenutak nakon kojeg klijent prestaje slati kolačić posluzitelju. Ukoliko je ovaj ključ izostavljen, klijent prestaje slati kolačić istekom web sjednice sa poslužiteljom.

Ključ Secure označava da klijent šalje kolačić samo ako se za komunikaciju klijenta i poslužitelja koristi sigurna veza (SSL).

Autentifikacija putem kolačića

Danas se kolačići često koriste za autentifikaciju korisnika uz tzv. poslužiteljske sjednice. Za svakog klijenta se na poslužitelju generira sjednica, koja se najčešće pohranjuje u bazu podataka. Identifikator sjednice zapisuje se u kolačić na klijentu. U svim zahtjevima prema poslužitelju klijent šalje kolačić sa identifikatorom sjedince koji poslužitelju koristi za daljnju obradu zahtjeva. Ovom metodom u kolačiću se ne pohranjuju osjetljive vrijednosti sjednice, već samo identifikator koji poslužitelju služi za dohvat iste.

Iako ova metoda autentifikacije nije preduvjet za CSRF napade, danas se vrlo često koristi u praksi.

Osnove HTML formi

HTML forme jedan su od načina na koji korisnik može podatke prenijeti na poslužitelj. Koncipirane su kao parovi vrijednosti ključ-vrijednost, slično kolačićima.

Jednostavan primjer koda HTML forme prikazan je u nastavku:

<form action="example.com/uplata", method="GET">
  <input type="number"    name="broj_racuna" placeholder="broj računa"> <br>
  <input type="number"    name="iznos_hrk"   placeholder="iznos">       <br>
  <input type="submit"    value="Slanje">
</form> 

Navedena forma ima dva para ključ-vrijednost, pri čemu su ključevi nazvani broj_racuna i iznos_hrk. Prikaz navedene forme u web pregledniku nalazi se u slici 2.

Slika 2: prikaz forme u web pregledniku

Detalji funkcioniranja i konfiguracije HTML formi nisu bitni u kontekstu CSRF napada, no bitan aspekt je način prenošenja formi s klijenta na poslužitelj.

Prijenos HTML formi korištenjem GET zahtjeva

Prvi pristup je korištenjem GET zahtjeva. Nakon što je korisnik ispunio formu, sadržaj forme se enkapsulira u URL (engl. Uniform Resource Locator). URL specifikacija definira generalnu shemu URL-a u idućem formatu:

scheme://user:password@host:port/path;params?query#frag

Segment query koristi se za predavanje parametara poslužitelju. Obično se nalazi iza putanje do resursa na poslužitelju, te je od njega odvojen upitnikom (?). Parovi ključ-vrijednost odvojeni su znakom &, dok su ključ i vrijednost u pojedinom paru odvojeni znakom jednakosti (=). Primjer URL-a koji koristi segment query glasi:

www.example.com?ime=ivan&prezime=horvat

Prikazani URL prenosi dva para ključ-vrijednost (ime i prezime).

U slučaju HTML formi, ključ poprima vrijednost naziva pojednog ključa u formi, dok se u vrijednost pridjeljenoj ključu upisuje korisnikov unos.

Vrlo bitna karakteristika ovog pristupa prijenosu HTML formi na poslužitelj je ta što je gore navedeni primjer URL-a moguće distribuirati kao običnu poveznicu (engl. link). Svaki korisnik koji bi u svojem web pregledniku kliknuo na navedenu poveznicu bi na poslužitelj poslao zahtjev sa istim parametrima, iako korisnik uopće nije popunjavao nikakvu HTML formu u svojem pregledniku.

Prijenos HTML formi korištenjem POST zahtjeva

Ukoliko HTML forma koristi POST zahtjev za prijenos na poslužitelj, parovi ključ-vrijednost enkodiraju se i šalju u tijelu zahtjeva prema poslužitelju. Razlika u odnosu na prethodno opisanu metodu je u tome što se korištenjem POST zahtjeva parametri forme ne nalaze u URL-u, odnosno nije moguće klikom na URL poslati parametre poslužitelju. Slika 3 prikazuje primjer prijenosa HTML forme korištenjem POST zahtjeva.

Slika 3: prijenos HTML forme korištenjem POST zahtjeva

Korisnik je u pregledniku u polje item upisao vrijednost bandsaw 2647, nakon čega je preglednik navedeni par ključ-vrijednost upisao u tijelo HTTP zahtjeva prema poslužitelju. Putanja zahtjeva glasi /inventory-check.cgi te je očito kako ne sadrži parametre, tj. vrijednosti forme.

Ideja i tijek CSRF napada

CSRF (engl. Cross-Site Request Forgery) napadi temelje se na korištenju kolačića za autentifikaciju korisnika, te na načinu na koji se HTML forme s klijenta šalju poslužitelju [2].

Zamislimo da neka banka ima mrežnu stranicu na kojoj svojim korisnicima nudi opciju uplate novca na neki drugi račun, primjerice za plaćanje režija. Jednostavan primjer HTML forme za ostvarivanje navedene funkcionalnosti prikazan je u nastavku.

<form action="example.com/uplata", method="GET">
  <input type="number"    name="broj_racuna">
  <input type="number"    name="iznos_hrk">
  <input type="submit"    value="Slanje">
</form> 

Forma se sastoji od dva para ključ-vrijednost. U prvom se specificira broj računa na koji se vrši uplata, dok se u drugom specificira iznos uplate. Također je vidljivo da se za slanje forme koristi GET zahtjev.

Pretpostavimo da navedena stranica banke koristi kolačiće za autentifikaciju korisnika. Kako je opisano u prošlim poglavljima, to spodrazumijeva da će korisnikov web preglednik, nakon inicijalne prijave u sustav, uz svaki HTTP zahtjev automatski dostavljati i kolačić koji identificira (i autentificira) korisnika.

Bitno je uočiti kako je i slanje HTML forme na poslužitelj zapravo običan HTTP zahtjev, te će korisnikov preglednik automatski u zaglavlje zahtjeva dodati vrijednost kolačića. Primjerice, ako je legitiman korisnik bankarske stranice odlučio na račun `1234` uplatiti `100` kuna, klikom na gumb “Slanje” web preglednik šalje idući zahtjev poslužitelju:

GET  /uplata?broj_racuna=1234&iznos_hrk=100 HTTP/1.1
Host: example.com
Cookie: id_sjednice="9876"

Poslužitelj će prvo pročitati vrijednost kolačića iz odgovarajućeg zaglavlja zahtjeva, te će zatim pokušati autentificirati korisnika. Nakon uspješne autentifikacije poslužitelj iz putanje resursa čita parove vrijednosti broj_racuna=1234 i iznos_hrk=100. Nakon toga se navedeni iznos šalje s računa legitimnog korisnika u račun s brojem 1234.

Međutim, navedeni zahtjev moguće je napraviti i najobičnijim klikom na URL:

example.com/uplata?broj_racuna=1234&iznos_hrk=100

bez ikakvog ispunjavanja formi, i to je najčešća metoda izvođenja CSRF napada. Ukoliko korisnik koji nije prijavljen u bankarsku stranicu otvori navedeni URL, poslužitelj bi vjerojatno invalidirao zahtjev jer klijent (web preglednik) nije poslao kolačić za identifikaciju, pošto korisnik nije prijavljen u sustav. Ukoliko korisnik koji jest prijavljen u bankarsku stranicu otvori navedeni URL, njegov web preglednik automatski šalje kolačić, čime se korisnik identificira i autentificira, te se navedeni iznos šalje na specificirani broj računa. Radi ovoga se CSRF napadi koji se temelje na GET metodama za prijenos HTML formi često nazivaju i “one click” napadi. Dovoljno je da korisnik koji je prijavljen u bankarsku stranicu klinke na malicioznu poveznicu, i iznos će biti uplaćen na broj računa napadača. Upravo opisani CSRF napad koristi se za HTML forme koje se šalju GET zahtjevima, a za POST forme procedura je opisana u nastavku.

CSRF napadi uz korištenje prijenosa HTML forme POST zahtjevom

CSRF napad moguće je izvesti i ukoliko se forma s klijenta šalje POST zahtjevom. U tom slučaju više nije moguće izvesti napad jednim klikom korisnika, jer se vrijednosti forme ne zapisuju u URL nego se šalju u tijelu zahtjeva. HTML forma za ostvarivanje navedene funkcionalnosti prikazana je u nastavku:

<form action="example.com/uplata", method="POST">
  <input type="number"    name="broj_racuna">
  <input type="number"    name="iznos_hrk">
  <input type="submit" value="Slanje">
</form> 

Forma je vrlo slična onoj iz prethodnog poglavlja gdje se koristio GET zahtjev za slanje forme, a jedina razlika je u tome što je u method atributu forme specifirana vrijednost POST. Klikom na gumb “Slanje” korisnikov web preglednik šalje idući POST zahtjev poslužitelju:

POST  /uplata HTTP/1.1
Host: example.com
Cookie: id_sjednice="9876"

broj_racuna=1234&iznos_hrk=100

U slučaju slanja forme poslužitelju korištenjem POST zahtjeva napadač mora konstruirati specifičnu “prerušenu” formu koja izgleda kao da radi benignu operaciju, a zapravo šalje zahtjev na poslužitelj banke:

<form action="example.com/uplata", method="POST">
  <!-- sakriveni dio forme -->
  <input type="number"    name="broj_racuna"  type="hidden" value="1234">
  <input type="number"    name="iznos_hrk"    type="hidden" value="9999">
  <!-- benigni dio forme   -->
  <input type="text"      name="benigno_polje">
  
  <input type="submit" value="Slanje">
</form> 

U prikazanom primjeru zloupotrebljava se atribut type HTML forme čija je vrijednost postavljena na hidden za ključeve broj_racuna i iznos_hrk, što znači da se navedena polja ne će prikazati u žrtvinom web poslužitelju. Međutim, klikom na gumb “Slanje” sva polja u formi će se poslati, uključujući i ona koja su postavljena kao sakrivena. Napadač navedenu formu treba objaviti na nekoj web stranici te “natjerati” žrtvu da ju ispuni odnosno pošalje.

Osim činjenice da ovu varijantu napada, za razliku od GET varijante, nije vrlo jednostavno izvesti, dodatna manjkavost ove varijante je u tome što se u zahtjevu prema poslužitelju banke šalje i dodatna vrijednost u formi, odnosno ključ benigno_polje. Ukoliko bankarski poslužitelj vrši validaciju forme, tj. provjerava da se u formi nalaze točno oni ključevi koji se moraju nalaziti, poslužitelj invalidira pridospjeli zahtjev, te napad ne uspijeva.

CSRF napadi maskirani u HTML slike

Ukoliko se za slanje forme koristi GET zahtjev, napad je moguće dodatno ubrzati na način da se eliminira potreba da žrtva klikne, odnosno otvori napadačev URL.

Web preglednici od samih početaka podržavaju opciju prikazivanja slika korištenjem img tagova. Primjer takvog taga glasi: <img src=“example.com/dubrava.jpg”>

Web preglednik automatski (bez ikakve intervencije korisnika) dohvaća sliku s URL-a specificiranog u src atributu slanjem GET zahtjeva na specificirani poslužitelj. Napadač u tom slučaju u src atribut web stranice upisuje maliciozni URL, primjerice:

example.com/uplata?broj_racuna=1234&iznos_hrk=100

žrtvin web preglednik otvaranjem napadačeve web stranice u svrhu dohvata slike automatski šalje GET zahtjev na bankarski poslužitelj i uplata se vrši bez ikakve žrtvine interakcije.

Prevencija CSRF napada

Postoje dva osnovna načina zaštite od CSRF napada [3], a oba se temelje na nasumično generiranoj tajnoj vrijednosti koju poslužitelj šalje legitimnom klijentu, a klijent primljenu vrijednost prenosi poslužitelju kao dodatni parametar HTML forme. Poslužitelj zatim provjerava jednakost poslane i primljene tajne vrijednosti. Taj se tajni ključ naziva CSRF token ili sinkronizacijski token.

Ideja je da napadač ne moze izvršiti CSRF napad jer ne može pogoditi tajnu vrijednost koju je poslužitelj poslao legitimnom klijentu, ako je vrijednost uopće poslana.

Prevencija korištenjem dodatnog polja forme

U ovom pristupu poslužitelj ugrađuje CSRF token dikretno u HTML formu, te pamti zadnju vrijednost tokena koju je poslao korisniku. Primjer ovako generirane forme prikazan je u nastavku:

<form action="example.com/uplata", method="GET">
  <input type="number"    name="broj_racuna">
  <input type="number"    name="iznos_hrk">
  
  <input type="text"      name="csrf_token" value="An*m&fNu7#j9" type="hidden">
 
 <input type="submit" value="Slanje">
</form> 

Klikom na gumb “Slanje” klijentov web preglednik automatski šalje i kljč csrf_token i vrijednost An*m&fNu7#j9, uz ostale vrijednosti forme. Poslužitelj zatim provjerava vrijednost zaprimljene vrijednosti ključa csrf_token: ako se ona razlikuje od zadnje poslane vrijednosti zahtjev se invalidira.

Prevencija korištenjem kolačića

Ovom metodom poslužitelj u klijentu zapisuje dodatni parametar u kolačić, primjerice csrf_token=An*m&fNu7#j9. Klijentov web poslužitelj zatim korištenjem jezika JavaScript sam ubacuje vrijednost iz kolačića u sve forme koje šalje poslužitelju.

Zaključak

CSRF napadi vrlo su opasni jer ih je u nekim slučajevima moguće izvesti a da žrtva toga nije svjesna. Radi svestranih primjena HTML formi u različite svrhe, poslijedice napada mogu biti od velikog utjecaja za žrtvu. Na sreću, CSRF napadi otkriveni su rano, a iako ranjivosti koje napadi zloupotrebljavaju nije moguće eliminirati, prevencija CSRF napada je relativno jednostavna za implementirati te bi se trebala koristiti pri obradi svake forme na web stranici.

Literatura

[1] David Gourley, Brian Totty, Marjorie Sayer, Anshu Aggarwal and Sailu Reddy. HTTP: The Definitive Guide. O'Reilly Media, Inc., 2002.

[2] Andrew Hoffman. Web Application Security. O'Reilly Media, Inc., 2020.

[3] Wikipedia: Cross-site request forgery. Pristupljeno: 12. 2020.

Izvori slika

Sve slike preuzete su iz knjige [1].