Înțelegerea falsificării cererilor în site .NET

Puteți crea numai aplicații web securizate ținând cont de securitate de la bun început. Acest lucru necesită o gândire a modurilor potențiale în care cineva ar putea ataca site-ul dvs. pe măsură ce creați fiecare pagină, formular și acțiune. De asemenea, este necesară înțelegerea celor mai frecvente tipuri de probleme de securitate și modul de abordare a acestora.

Cel mai obișnuit tip de gaură de securitate dintr-o pagină Web permite unui atacator să execute comenzi în numele unui utilizator, dar necunoscut utilizatorului. Atacul de tip "forgery" din cadrul site-ului web exploatează încrederea pe care un site Web-ul a stabilit-o deja cu browserul web al utilizatorului.

În acest tutorial, vom discuta despre ce este un atac de tip fals și care este modul în care acesta este executat. Apoi, vom construi o aplicație ASP.NET MVC simplă, care este vulnerabilă la acest atac și va repara aplicația pentru a împiedica aceasta să se întâmple din nou.


Ce este falsificarea cererii între site-uri?

Cererea de falsificare a solicitării în mai multe locații presupune mai întâi că victima a autentificat deja pe un site țintă, cum ar fi un site bancar, Paypal sau alt site care trebuie atacat. Această autentificare trebuie stocată într-un mod astfel încât, dacă utilizatorul să părăsească site-ul și să revină, aceștia sunt încă văzuți ca fiind conectați de către site-ul țintă. Atacatorul trebuie să-l aducă pe victima să acceseze o pagină sau un link care va executa o solicitare sau o postare pe site-ul țintă. Dacă atacul funcționează, atunci site-ul țintă va vedea o cerere venită de la victimă și va executa cererea ca acel utilizator. Acest lucru permite, în realitate, atacatorului să execute orice acțiune dorită pe site-ul vizat ca victimă. Rezultatul potențial ar putea transfera bani, reseta o parolă sau poate schimba o adresă de e-mail la site-ul web vizat.

Cum funcționează atacul

Actul de a obtine victima sa utilizeze o legatura nu le cere sa faca clic pe un link. Un simplu link de imagine ar putea fi de ajuns:

Includerea unei legături, cum ar fi aceasta, într-un post de pe forum, altfel aparent inofensiv pe forum, în comentariu pe blog sau pe site-ul social media, ar putea prinde un utilizator care nu știe. Exemple mai complexe utilizează JavaScript pentru a crea o cerere de post HTTP complet și a le trimite la site-ul țintă.


Construirea unei aplicații web vulnerabile în ASP.NET MVC

Să creați o aplicație ASP.NET MVC simplă și să o lăsați vulnerabilă la acest atac. Voi folosi Visual Studio 2012 pentru aceste exemple, dar acest lucru va funcționa și în Visual Studio 2010 sau Visual Web Developer 2010 va funcționa dacă ați instalat suport pentru MVC 4 care poate fi descărcat și instalat de la Microsoft.


Începeți prin crearea unui nou proiect și alegeți să utilizați Proiectul Internet șablon. Fie View Engine va functiona, dar aici voi folosi motorul de vizualizare ASPX.

Vom adăuga un câmp în tabela UserProfile pentru a stoca o adresă de e-mail. Sub Server Explorer extinde Conexiuni de date. Ar trebui să vezi Conectare implicită create cu informațiile pentru conectări și membri. Faceți clic dreapta pe USERPROFILE tabelul și faceți clic pe Deschideți definiția tabelului. Pe linia goală de sub Nume de utilizator tabel, vom adăuga o nouă coloană pentru e-mail. Denumiți coloana adresa de email, da-i tipul nvarchar (MAX), și verificați Permite zerourile opțiune. Acum faceți clic pe Actualizați pentru a salva noua versiune a tabelului.

Acest lucru ne oferă un șablon de bază al unei aplicații web, cu suport pentru conectare, foarte asemănător cu ceea ce mulți scriitori ar începe să încerce să creeze o aplicație. Dacă rulați aplicația acum, veți vedea că aceasta este afișată și este funcțională. presa F5 sau utilizare DEBUG -> Porniți depanarea din meniu pentru a accesa site-ul web.


Să creăm un cont de testare pe care îl putem folosi pentru acest exemplu. Faceți clic pe Inregistreaza-te link și creați un cont cu orice nume de utilizator și parolă pe care doriți. Aici o să folosesc un cont numit testuser. După crearea, veți vedea că acum sunt conectat ca testuser. După ce ați făcut acest lucru, ieșiți și adăugați o pagină la această aplicație pentru a permite utilizatorului să își schimbe e-mailul.


Înainte de a crea această pagină pentru a schimba adresa de e-mail, trebuie mai întâi să efectuăm o modificare a aplicației, astfel încât codul să fie conștient de noua coloană pe care tocmai am adăugat-o. Deschide AccountModels.cs fișier în modele folder și actualizați USERPROFILE clasa pentru a se potrivi cu următoarele. Aceasta ne spune clasa despre coloana nouă în care vom stoca adresa de e-mail pentru cont.

[Table ("UserProfile")] public class UserProfile [cheie] [DatabaseGeneratedAttribute (DatabaseGeneratedOption.Identity)] public int UserId get; a stabilit;  șir public Nume utilizator get; a stabilit;  șir public EmailAddress get; a stabilit; 

Deschide AccountController.cs fişier. După RemoveExternalLogins adăugați următorul cod pentru a crea o acțiune nouă. Acesta va primi e-mailul curent pentru utilizatorul conectat și îl va trimite la vizualizarea acțiunii.

publicul ActionResult ChangeEmail () // Obțineți login-ul șir de utilizator username = WebSecurity.CurrentUserName; string curentEmail; folosind (UsersContext db = noi UsersContext ()) UserProfile user = db.UserProfiles.FirstOrDefault (u => u.UserName.ToLower () == username); curentEmail = user.EmailAddress;  retur View (curentEmail); 

De asemenea, trebuie să adăugăm viziunea corespunzătoare pentru această acțiune. Acesta ar trebui să fie un fișier numit ChangeEmail.aspx sub Vizualizări \ Cont pliant:

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage"%>  Schimbați adresa de e-mail   

Schimbați adresa de e-mail

Adresa de email curenta: <%= Model ?? "Nu există e-mail curent"%>

<% using(Html.BeginForm()) %> <% %>

Acest lucru ne oferă o nouă pagină pe care o putem utiliza pentru a schimba adresa de e-mail pentru utilizatorul conectat în prezent.


Dacă executăm această pagină și mergem la / Cont / ChangeEmail acțiune, acum vedem că în prezent nu avem un e-mail. Dar avem o casetă text și un buton pe care îl putem folosi pentru a corecta asta. În primul rând, trebuie să creăm acțiunea care va fi executată, atunci când formularul de pe această pagină este trimis.

[HttpPost] public ActionResult ChangeEmail (modelul ChangeEmailModel) string username = WebSecurity.CurrentUserName; folosind (UsersContext db = noi UsersContext ()) UserProfile user = db.UserProfiles.FirstOrDefault (u => u.UserName.ToLower () == username); user.EmailAddress = model.NewEmail; db.SaveChanges ();  // Și pentru a verifica schimbarea, primiți e-mailul din profil ChangeEmailModel newModel = new ChangeEmailModel (); folosind (UsersContext db = noi UsersContext ()) UserProfile user = db.UserProfiles.FirstOrDefault (u => u.UserName.ToLower () == username); newModel.CurrentEmail = user.EmailAddress;  retur View (nouModel); 

După efectuarea acestei modificări, rulați site-ul Web și reveniți din nou la / Cont / ChangeEmail acțiune pe care tocmai am creat-o. Acum puteți introduce o nouă adresă de e-mail și faceți clic pe Schimbă e-mail buton pentru a vedea că adresa de e-mail va fi actualizată.


Atacul site-ului

După cum este scris, aplicația noastră este vulnerabilă la un atac de tip "forgery request". Să adăugăm o pagină web pentru a vedea acest atac în acțiune. Vom adăuga o pagină în cadrul site-ului care va schimba e-mailul la o altă valoare. În HomeController.cs fișier vom adăuga o nouă acțiune numită AttackForm.

publicul ActionResult AttackForm () retur View (); 

De asemenea, vom adăuga o vizualizare pentru acest nume AttackForm.aspx sub / Vizualizări / Home pliant. Ar trebui să arate astfel:

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage"%>  Formă de atac   

Formă de atac

Această pagină are un formular ascuns, pentru a vă ataca, schimbând adresa de e-mail:

Pagina noastră vă anunță cu bună intenție intenția sa rea, care, desigur, nu ar face un adevărat atac. Această pagină conține o formă ascunsă care nu va fi vizibilă pentru utilizator. Apoi utilizează Javascript pentru a trimite automat acest formular atunci când pagina este încărcată.


Dacă rulați site-ul din nou și mergeți la / Acasă / AttackForm pagina, veți vedea că se încarcă foarte bine, dar fără nici un indiciu exterior că sa întâmplat ceva. Dacă acum mergeți la / Cont / ChangeEmail Totuși, veți vedea că adresa dvs. de e-mail a fost modificată [email protected]. Aici, desigur, intenționăm să facem acest lucru evident, dar într-un atac real, este posibil să nu observați că e-mailul dvs. a fost modificat.


Ameliorarea falsificării cererilor cross-site

Există două modalități principale de atenuare a acestui tip de atac. În primul rând, putem verifica trimiterea de la care ajunge cererea web. Acest lucru ar trebui să spună cererea atunci când o trimitere de formular nu vine de la serverul nostru. Acest lucru are două probleme, totuși. Multe servere proxy elimină aceste informații de recomandare, fie în mod intenționat pentru a proteja confidențialitatea, fie ca efect secundar, ceea ce înseamnă că o solicitare legitimă nu poate conține aceste informații. De asemenea, este posibil ca un atacator să falsifice trimiterea, deși crește complexitatea atacului.

Cea mai eficientă metodă este aceea de a solicita existența unui jeton specific utilizatorului pentru fiecare trimitere de formular. Valoarea acestui simbol trebuie generată aleator de fiecare dată când formularul este creat, iar formularul este acceptat numai dacă este inclusă tokenul. Dacă simbolul lipsește sau este inclusă o altă valoare, nu permitem trimiterea formularului. Această valoare poate fi stocată fie în starea sesiunii de utilizator, fie într-un modul cookie pentru a ne permite să verificăm valoarea când este trimis formularul.

ASP.NET face acest proces ușor, deoarece suportul CSRF este construit. Pentru al utiliza, trebuie doar să facem două modificări pe site-ul nostru.


Rezolvarea problemei

În primul rând, trebuie să adăugăm tokenul unic la formular pentru a schimba e-mailul utilizatorului când îl afișăm. Actualizați formularul în ChangeEmail.aspx vizualizați sub / Cont / ChangeForm:

<% using(Html.BeginForm())  %> <%: Html.AntiForgeryToken() %> <%: Html.TextBoxFor(t=>t.NewEmail)%>  <%  %>

Această nouă linie: <%: Html.AntiForgeryToken() %> spune ASP.NET să genereze un jeton și să îl plaseze ca un câmp ascuns în formă. În plus, cadrul se ocupă de plasarea acestuia într-o altă locație în care aplicația o poate accesa mai târziu pentru ao verifica.

Dacă încărcăm acum pagina și ne uităm la sursă, vom vedea această nouă linie, în formă, redată la browser. Acesta este simbolul nostru:

Trebuie, de asemenea, să facem o schimbare a acțiunii noastre pentru a permite acesteia să știe că am adăugat acest jeton și că ar trebui să verifice tokenul înainte de a accepta formularul afișat.

Din nou, acest lucru este simplu în ASP.NET MVC. În partea de sus a acțiunii pe care am creat-o pentru a gestiona formularul postat, cel cu [HttpPost] atributul adăugat, vom adăuga un alt atribut numit [ValidateAntiForgeryToken]. Aceasta face ca începutul acțiunii noastre să pară acum:

 [HttpPost] [ValidateAntiForgeryToken] public ActionResult ChangeEmail (modelul ChangeEmailModel) string username = WebSecurity.CurrentUserName; * restul funcției omite *

Să testați asta. Mai întâi du-te la / Cont / ChangeEmail și restabiliți adresa de e-mail pentru contul dvs. la o valoare cunoscută. Apoi ne putem întoarce la / Acasă / AttackForm pagina și din nou codul de atac încearcă să ne schimbe e-mailul. Dacă vă întoarceți la / Cont / ChangeEmail din nou, de data aceasta veți vedea că e-mailul introdus anterior este încă sigur și intact. Modificările aduse formularului și acțiunii noastre au protejat această pagină de atac.

Dacă ar trebui să te uiți direct la formularul de atac (ușor de făcut prin eliminarea