Prevenirea XSS în ASP.NET

Multe probleme de securitate a site-ului provin din încrederea utilizatorului prea mult. Cei mai mulți utilizatori ai aplicației dvs. web vor face doar ceea ce au nevoie să facă, un utilizator curios sau rău intenționat va dori adesea să împingă marginile accesului. La aceste margini, găurile de securitate apar adesea în aplicația dvs. Am scris despre prevenirea a două tipuri comune de vulnerabilități, SQL Injection și Cross Site Request forgery, în aplicațiile ASP.NET înainte. Acest articol analizează prevenirea Scripting-ului Cross Site, un al treilea tip comun de vulnerabilitate în site-uri web.

În timp ce un cadru modern face multe pentru a face aceste atacuri mai dificile, cred că ar trebui să avem mai întâi o înțelegere a modului în care o aplicație este vulnerabil la un atac. În primul rând, să examinăm ce este Scripting Cross Site și cum poate fi exploatat.

Ce este Scripting Cross Site

Cross Scripting (adesea abreviat ca XSS) permite injectarea de scripturi malware într-un site web de încredere. Această injecție se face fără cunoștințele utilizatorului. Scriptul injectat este executat ca și cum ar proveni de pe site-ul original. Scriptul malware poate accesa astfel orice resurse ale site-ului web găzduit la care ar avea acces utilizatorul, cum ar fi cookie-urile sau jetoanele de sesiune.

Deschiderea pentru un atac de scripting pe site-uri încrucișate apare atunci când o aplicație web afișează intrări de la utilizatori sau resurse externe fără validarea corectă sau codarea acesteia. În majoritatea atacurilor de scripting pe site-uri, atacatorul încearcă să injecteze JavaScript în pagina web a unui server de încredere. Atacatorul poate încerca, de asemenea, să injecteze HTML, Flash sau orice altceva ce browserul va executa. Indiferent de scenariu, obiectivul rămâne să primească browserul pentru a executa codul alegerii atacatorului.

Un atac persistente XSS

Există trei categorii de atacuri de script-uri încrucișate, împărțite prin metoda injecției și prin metoda de prevenire a atacului. În primul tip de atac, script-ul este stocat permanent pe serverul țintă și, prin urmare, se numește atac de scripting persistent la intersecție. Acest atac încearcă să încorporeze scriptul malware într-un articol cum ar fi un post de pe forum stocat într-o bază de date sau un domeniu aparent benign, cum ar fi pagina de pornire a unui utilizator al bazei de date. Cu scenariul persistent, fiecare vizitator al site-ului care vede postul, mesajul sau alt articol compromis devine o potențială victimă a atacului.

Atacatorii care încearcă acest tip de atac vizează, în general, câmpuri de comentarii, forumuri, medii sociale și alte domenii în care este de așteptat o intrare oarecum arbitrară a utilizatorului final și este o parte normală a aplicației. Atacatorul poate include scenariul într-un post pe forum într-o altă parte a unei conversații. De fiecare dată când cineva vizualizează postarea, scriptul va fi executat.

Un atac XSS reflectat

În cel de-al doilea tip de atac de scripting încrucișat, cunoscut ca fiind scripting încrucișat, atacatorul livrează scriptul injectat site-ului vulnerabil, astfel încât acesta să fie imediat returnat utilizatorului. Metodele comune de a face acest lucru, pagini țintă unde intrarea utilizatorului devine parte a ieșirii unei pagini. O pagină de căutare poate afișa termenii de căutare pentru utilizator și ar putea oferi o priză pentru acest atac. Scriptul injectat la intrarea unui utilizator nu ar trebui să fie stocat niciodată de aplicația web.

Atacurile bazate pe DOM

Al treilea atac de scripting pentru site-uri încrucișate are loc în întregime în browser. Atacul funcționează prin manipularea modelului intern al paginii web din browser-ul cunoscut sub numele de DOM și sunt denumite atacuri bazate pe DOM. Acestea din nou permit atacatorului să execute cod rău intenționat, dar codul returnat de server este manipulat în JavaScript executabil de către pagina web.

În cele din urmă, un atac scripting pe site-uri încrucișate este un atac de scripting pe site-uri, indiferent de modul în care este livrat. Deoarece codul injectat provine de la un server de încredere, acesta poate fi executat de multe ori sub permisiunile site-ului. Prin urmare, se poate acționa ca și cum ar fi fost cod nativ pe site-ul web. 

Un atac reușit de scripting pe site-uri ar putea permite accesul la cookie-urile pe o pagină Web. Aceste cookie-uri pot conține informații sensibile, inclusiv identificatori de sesiuni care ar permite atacatorului să se implice în utilizatorul atacat. De asemenea, atacul poate schimba conținutul HTML pe o pagină pentru a afișa un formular de autentificare fals și pentru a fura acreditările utilizatorului. Atacatorul ar putea examina și trimite orice conținut al paginii care să permită capturarea unor informații sensibile, cum ar fi numerele contului. Un atac mai avansat ar putea, de fapt, să instaleze un logger cheie care trimite un informator introdus în pagina web unui atacator.

Protejarea de atacuri de la site-urile de scripting

Ameliorarea script-urilor de site-uri incrucisate necesita increderea in orice intrare de la un utilizator sau de la o alta sursa externa. Aplicația web trebuie să trateze aceste date ca potențial periculoase, indiferent de sursă. Să ne uităm la câteva metode specifice ASP.NET pentru a preveni aceste atacuri folosind componentele construite în cadru și bibliotecile disponibile în mod liber.

Validați toate intrările

Aplicația web trebuie să valideze orice intrare în aplicație înainte de a fi utilizată. La fel ca în cazul altor atacuri de injectare, cum ar fi SQL Injection. Aplicația validează de preferință această intrare împotriva unei liste albe de valori acceptabile. Validarea elimină sau înlocuiește orice componente neașteptate ale intrării cu o valoare codificată. O metodă de listă neagră, care elimină numai o listă de caractere nedorite cunoscute, poate fi utilizată, dar este mai vulnerabilă la noile metode de atac.

Dacă știm că o valoare ar trebui să fie întotdeauna un număr întreg, atunci puteți valida codul de intrare utilizând:

int memberId; dacă (! int.TryParse (externValue, out memberId)) returnează RedirectToAction ("InputError");  

Dacă cadrul nu poate parsa materialul anterior preluat externalValue ca număr întreg, codul redirecționează către o pagină care ar afișa o eroare. În caz contrar știm asta Membru ID conține o valoare întregă. Acest proces funcționează și cu alte tipuri de bază. Unele tipuri mai obișnuite oferă, de asemenea, metode pentru validarea informațiilor. Plasa uri clasa conține o metodă IsWellFormedUriString care poate valida o adresă URL. Aceasta ar permite validarea faptului că o intrare a unei pagini de pornire a unui utilizator conține o adresă URL validă înainte de afișare.

var utilizatorHomePage = userRecord ["homepage"]; dacă (! Uri.IsWellFormedUriString (newUrl, UriKind.Absolute)) Model.homepage = "niciunul";  altceva Model.homepage = Html.Encode (userHomePage);  

Alte tipuri de date mai complexe necesită o validare mai complexă. Validarea unui câmp de număr de carte de credit ar putea elimina orice caractere din șir care nu sunt cifre. Validarea șirurilor mai complexe ar putea necesita expresii regulate. Validarea unei clase poate necesita și verificări mai complexe.

Solicitarea validării ASP.NET

ASP.NET oferă o protecție eficientă împotriva atacurilor reflectate utilizând validarea solicitărilor. Dacă ASP.NET detectează marcarea sau codul într-o solicitare, aruncă o excepție "o valoare potențial periculoasă a fost detectată" și oprește procesarea cererii.

Deși este valoroasă, există momente în care trebuie să permiteți aceste valori într-o solicitare. Un exemplu comun se referă la permiterea intrării textului bogat într-o formă. În aceste cazuri, din păcate, validarea solicitării este prea des dezactivată pentru întregul site. O soluție mai bună oprește această validare numai acolo unde este necesar. În versiunile anterioare de ASP.NET, adăugând validateRequest = "false" la Pagină directiva în Webforms va dezactiva validarea pentru o pagină. În ASP.NET MVC, adăugând [ValidateInput (false)] atributul la o acțiune a controlerului oprește validarea acelei acțiuni, adăugând în același timp [AllowHtml] atributul dezactivează validarea pentru un câmp.

ASP.NET 4.0 a modificat validarea solicitării în mai multe moduri. Această versiune și versiunile ulterioare ale cadrului de validare devreme în cererea HTTP. Validarea se aplică și în cazul tuturor solicitărilor ASP.NET și nu numai .aSPX solicitări de pagină. Aceasta include și module personalizate HTTP. Paginile care se bazează pe comportamentul original pot reveni la metoda mai veche prin setarea requestValidationMode atribut în web.config fișier la versiune 2.0.

 

Chiar mai bine, este de a dezactiva acest lucru numai pentru paginile unde este nevoie, folosind sintaxa în web.configfişier:

     

ASP.NET 4.5 a adăugat capacitatea de a amâna validarea până la solicitarea datelor. Setarea requestValidationMode atribut în dvs. web.config fișier la versiune 4.5 activează acest nou comportament.

 

ASP.NET 4.5 a adăugat de asemenea HttpRequest.Unvalidated proprietate. Utilizarea acestei proprietăți permite accesul mai ușor la valoarea formularului nevalidată acolo unde este necesar. Prin combinarea validării întârziate cu nevalidate proprietate, puteți accesa valorile nevalide atunci când este necesar, dar protejați alte intrări de formă.

Codarea HTML

Înainte de a afișa date exterioare pe o pagină Web, HTML-ul dvs. ar trebui să fie codificat, astfel încât acesta să nu fie procesat de browser. De exemplu, luați o pagină ASP.NET scrisă astfel încât să poată fi transmis un mesaj pentru afișare, cum ar fi o actualizare a stării. O aplicație ar putea folosi această pagină pentru a arăta utilizatorului că contul său a fost creat fără erori. URL-ul pentru această pagină ar arăta, în mod normal, similar cu http: // APPNAME / placeorder / cont de + Creat. Pagina rezultată afișează mesajul utilizatorului cu un câmp, cum ar fi:

<%= Html.Label("Message", Model.message) %> 

... și se afișează ca:

Dacă schimbăm apelul URL la http: / APPNAME / placeorder /, acum avem ceva diferit.

Scenariul ar putea fi ceva desigur și nu doar caseta de alertă inofensivă care apare aici. Solicitarea validării va prinde exemplele de mai sus și va returna o excepție înainte de afișare. Dacă este dezactivată, atunci codarea ieșirii împiedică atacul.

ASP.NET facilitează codarea datelor pentru a preveni atacurile. Versiunile anterioare ale MVC utilizând sintaxa Webform conțineau adesea un cod precum cel care nu a codat codul HTML.

<%= status >

A trebuit să codificați manual ieșirea astfel încât orice cod HTML să fie convertit într-un format de afișare. Asa ca < caracterul devine șir <. Html.Encode funcția oferă această conversie. Astfel, forma mai sigură de cod devine:

<%= Html.Encode(status) >

ASP.NET MVC a introdus mai târziu o sintaxă pentru a face acest lucru într-un singur pas prin înlocuire <= cu <: astfel încât codul poate fi redus la:

<%: status >

Utilizând motorul de vizualizare Razor, toate ieșirile sunt codate HTML dacă nu utilizați în mod specific o metodă pentru a nu le codifica. În Razor, codul echivalent cu cele de mai sus devine:

@stare

Razorul gestionează automat codarea HTML a oricărui șir stare conține. Într-un caz în care trebuie să redați datele brute, puteți utiliza HTML.Raw () metodă. Pentru a afișa rezultatul fără codificare, putem folosi:

@ Html.Raw (status)

În acest exemplu, codul de mai sus ar face vulnerabilitatea aplicației noastre din nou. Deci, există câteva situații în care nu trebuie să codificați ieșirea. Dacă dezactivați această funcție pe un câmp, trebuie să aveți grijă deosebită pentru a vă asigura că datele sunt dezinfectate înainte de afișare. Din fericire, există o bibliotecă care vă ajută în acest scop, făcând totodată și mai mult pentru a vă proteja aplicația de la scriptingul pe site-uri.

Biblioteca AntiXSS

Dacă scrieți o aplicație ASP.NET, ar trebui să utilizați Biblioteca AntiXSS pentru ASP.NET. De pe site-ul proiectului, "AntiXSS oferă o multitudine de funcții de codificare pentru introducerea de către utilizatori, inclusiv atribute HTML, atribute HTML, XML, CSS și JavaScript".

Biblioteca conține metode destinate dezinfectării datelor în afara bazei pe baza utilizării intenționate a acestor date. Aceste metode utilizează abordarea bazată pe lista albă preferată. Aceasta înseamnă că datele codificate, destinate unui atribut HTML, pot fi dezinfectate pentru a conține numai date valide pentru un atribut HTML. Tradiționalul ASP.NET HtmlEncode Metodele utilizează abordarea listarea neagră care codifică numai anumite caractere potențial periculoase.

Microsoft a început să includă rutine de bază din această bibliotecă în ASP.NET 4.5 într-un nou System.Web.Security.AntiXss Spațiu de nume. De asemenea, puteți configura cadrul pentru a utiliza aceste metode AntiXSS în locul rutinelor de codificare încorporate. Puteți face acest lucru prin setarea encoderType atributul lui httpRuntime în web.config dosar pentru cerere:

 

În cazul în care aplicația dvs. prezintă o afișare semnificativă a datelor externe, atunci utilizarea programului AntiXSS va face mult pentru a vă proteja aplicația de scriptingul inter-site. Dacă utilizați ASP.NET 4.5, schimbarea aplicației dvs. pentru a utiliza noile metode AntiXSS pentru codarea implicită oferă o protecție mai mare pentru aplicația dvs. web.

În concluzie

Împiedicarea scripting-ului de site-uri încrucișate este mai greu decât pare inițial. OWASP enumeră peste 80 de vectori care pot fi direcționați utilizând atacuri de scripting pe site-uri. Organizația menționează, de asemenea, aceste vulnerabilități ca fiind a treia în lista lor din 2013 a primelor zece vulnerabilități web.

Dacă nu vă asigurați că toate datele din afară introduse în aplicația dvs. au fost scoase corect sau nu validați intrarea înainte de ao plasa pe o pagină de ieșire, lăsați aplicația dvs. web vulnerabilă la scriptingul între site-uri. În ASP.NET, acest lucru se poate face prin:

  1. Validarea tuturor intrărilor externe în aplicație înainte de a fi afișate pe o pagină web.
  2. Utilizați Validarea Solicitării peste tot în cazul în care aplicația dvs. nu trebuie în mod special să o dezactiveze, cum ar fi un formular care permite o intrare HTML bogată. Dacă trebuie să permiteți informații nevalide, lăsați validarea peste tot în aplicația dvs..
  3. Codificați codul HTML înainte de a afișa date externe pe o pagină web
  4. Utilizați metodele bazate pe AntiXSS incluse în ASP.NET 4.5 și utilizați biblioteca AntiXSS pentru versiunile mai vechi ale ASP.NET.
Cod