Tales from under the Mountain

Sanitizacija HTML koda

XSS je jedna od najopasnijih ranjivosti web-a, kada pogledamo šta je sve moguće s njom. Iako bi neki stručnjaci (kao recimo Blind Injection), sigurno daleko bolje i podrobnije objasnili o čemu se ovde radi, za potrebe ovog posta dovoljno je reći da je u pitanju iskorišćavanje jedne od osovnoh osobina browser-a, a to je da izvrši skript koji postoj ina strani. Zlonamerni korisnik ubacuje (“injektuje”) skript koji može da ima razne efekte, od krađe cookies koje korisnik ima, pa do redirekcije na neku stranu pravljenu za phishing.

OK, a kako to nastaje?

Postoje različiti načini kako da se skript “ubode” u HTML stranu, čak i ako ne koristite Rich Text editore. Problem nastaje kod ispisa onoga što je korisnik uneo, pogotovo ako to radimo bez ikakve provere. Recimo, imamo jedan textarea u koji želimo da korisnik upiše komentar koji posle prikažemo na strani. Ukoliko je ono što je korisnik napisao nešto bezazleno, to je OK, ali šta ako odluči da sadržaj textarea polja bude u stvari neki JS kod koji će uraditi nešto zlobno? Ja ga prosto ispisujem na strani, i presto!, nastaje problem.

Rešenje je prosto!

Enkodujte output. Ukoliko koristite ASP.NET, možete da koristite različite biblioteke, AntiXSS bilbioteka od Microsoft-a je jedna od boljih. ASP.NET MVC koristi helper metod Html.Encode() koji to isto radi. Isto tako, ASP.NET engine ima direktivu koja automatski baca exception ako se pojavi bilo kakav HTML kod u input stream-u, a koje se zove ValidateRequest.

Enkodovanje prosto zameni svaki karakter HTML kodom, tako da “<” postaje “&lt;” i slično. Ovo omogućava da se HTML kod prikaže kao običan tekst u browser-u. Problem rešen.

Pa čemu onda blog post?

Jer ponekad postoji potreba, kao što je sada imam, da se korisnicima dozvoli da unose HTML kod. Pored toga, nije svaki HTML kod opasan; ne postoji ništa opasno kod sledeće kombinacije:

 

   1: <p>Ja sam <b>boldovan</b>.</p>

Nedavno sam naleteo na problem da mi se traži da omogućim sređivanje dužih tekstova na web-u. Ništa specijalno, samo da se omogući pravljenje paragrafa, osnovna stilizacija teksta, dodavanje linkova…dakle, ništa “fancy”. Međutim, kada sam pogledao čak i minimalne RTE-ove, svaki od njih omogućava editovanje HTML koda direktno. Još gore, kada jednom omogućim ovako nešto korisnicima, ne mogu više da se oslanjam na Html.Encode(), jer na nekim ispisima moram da ga namenski isključim. Dakle, potrebna mi je sanitizacija.

Trenutno, ako pokušate da nađete rešenje za ovaj problem, verovatno ćete naići na razna rešenja koja koriste regex-ove. U poslednje vreme, ovakav pristup se smatra lošim, uglavnom jer ne pokriva sve slučajeve, recimo atribute na tagovima (pored toga, setimo se šta se priča za programere i regex-ove). Drugo rešenje je da imate neke od pseudo-markup editora, odnosno dijalekata, kao što su Markdown ili Textile. Ukoliko su vam korisnici sposobni da ovo koriste, problem je rešen. Na moju štetu, ovako nešto nije bilo moguće.

Posle pretrage, naleteo sam na verziju 3.1 AntiXSS bilbioteke. Na moje čudo, ta verzija je dodala dva nova metoda za sanitizaciju GetSafeHtml() i GetSafeHtmlFragment(). Prvi služi za sanitizaciju celih HTML strana, dok drugi služi za sanitizaciju fragmenata. Ono što će ova dva metoda uraditi je da uklone sve “štetne” tagove, odnosno, tačnije rečeno, sve tagove koji su u whitelist-u koji bilbioteka koristi interno. Korišćenje je veoma prosto:

   1: string HtmlFragment = "<b>Some good input.</b><script>document.write('some bad input');</script>";
   2: string sanitized = AntiXss.GetSafeHtmlFragment(HtmlFragment);

Posle ovoga, sanitizied string neće više sadržavati <script> tagove. Slično tome, kao dodatak, HTML će biti well-formed, u smislu da će svi nezatvoreni tagovi biti zatvoreni i slično. Nažalost, trenutno je dokumentacija pomalo škrta; kada jednom instalirate bilbioteku, imate test harness ali koji ne pokazuje sanitizaciju, kao i sample projekat k(web forms aplikaciju) koja vam daje ideju kako se AntiXSS bilbioteka i ceo security engine koji dolaze sa njom koriste. Da bih probao bilbioteku, napisao sam par (veoma) jednostavnih unit testova koji pokazuju kako se koristi bilbioteka. Projekat na SkyDrive-u, i možete ga preuzeti odatle.

Tema XSS-a je svakako daleko veća od ovog blog posta, ali sam želeo da dam odgovor ljudima koji možda takođe tragaju za pametnijim i robustnijim načinom sanitizacije nesigurnog HTML koda koji dolazi od korisnika, ali bez da ukinemo kompletno mogućnost korisnicima koji nisu toliko vešti u korišćenju računara da imaju lepo formatiran tekst na sajtu.

Out.

B.D.

Posted: Dec 14 2009, 03:23 PM by blackdwarf | with no comments
Filed under: , ,
Leave a Comment

(required) 

(required) 

(optional)

(required) 

Are you a human?