În tutorialul de astăzi, vom învăța cum să protejăm fără durere aplicația CodeIgniter (pentru versiunea 2.0) împotriva atacurilor de falsificare a solicitărilor transfrontaliere. Biblioteca pe care o vom crea astăzi va automatiza toate mecanismele de protecție, făcând site-ul dvs. mai puternic și mai sigur.
Solicitările de interogare de tip Cross-Site se bazează pe formulare neprotejate pe site-urile dvs..
Un atacator ar putea crea o formă falsă pe site-ul său - de exemplu un formular de căutare. Acest formular ar putea avea ascunse intrări care conțin date rău intenționate. Acum, formularul nu este trimis la site-ul atacatorului pentru a efectua căutarea; în realitate, forma subliniază ta site-ul! Întrucât site-ul dvs. web va avea încredere că formularul este autentic, acesta trece prin și execută acțiunile solicitate (și probabil rău intenționate).
Imaginați-vă că un utilizator este conectat la site-ul dvs. și este redirecționat către site-ul atacatorului din anumite motive (phishing, XSS, îl numiți). Formularul atacatorului poate indica pe site-ul dvs. formularul de ștergere a contului. Dacă utilizatorul efectuează o căutare pe site-ul atacatorilor, contul său va fi apoi șters fără ca el să știe!
Există numeroase modalități de a preveni aceste tipuri de atacuri.
POST
solicitați, comparați tokenul trimis cu cel de pe magazin și, dacă diferă, respingeți solicitarea. Totuși, site-ul dvs. trebuie protejat împotriva XSS, deoarece, dacă nu este, această metodă devine inutilă.Va trebui să facem trei lucruri pentru fiecare solicitare:
POST
solicitați, validați că jetonul trimis. Pentru a face acest lucru automat, vom folosi cârligele CodeIgniter. Cârligele ne permit să executăm toate acțiunile din diferite părți ale cererii. Avem nevoie de trei:
Să începem. Vom merge pas cu pas pentru a explica totul cât mai bine posibil. Vom crea metoda care generează primul jeton, astfel încât să putem testa totul corect după aceea. Creați un fișier în dvs. sistem / aplicație / cârlige
dosarul numit "csrf.php
"și introduceți următorul cod:
CI = & get_instance ();
Sperăm că ceea ce am adăugat mai sus ar trebui să pară mai degrabă pentru tine. Creăm o clasă, numită CSRF_Protection
, o variabilă de instanță pentru a ține instanța CodeIgniter, două variabile statice pentru a ține numele parametrului care va stoca tokenul și unul pentru a stoca tokenul în sine pentru a avea acces ușor în întreaga clasă. În cadrul constructorului de clasă (__construi
), pur și simplu preluăm instanța CodeIgniter și stocăm-o în variabila de instanță corespunzătoare.
Notă: "Numele parametrului" este numele câmpului care deține jetonul. Deci, pe formulare, este numele intrării ascunse.
După constructorul de clasă, lipiți următorul cod:
/ ** * generează un jeton CSRF și îl stochează în sesiune. Se generează doar un singur simbol pe sesiune. * Aceasta trebuie legată de un cârlig post-controler și înainte de cârligul * care apelează metoda inject_tokens (). * * @return void * @author Ian Murray * / funcția publică generate_token () // Încărcați biblioteca sesiunilor dacă nu încărcați $ this-> CI-> load-> library ('session'); dacă ($ this-> CI-> session-> userdata (self :: $ token_name) === FALSE) // Generați un jeton și păstrați-l în sesiune, deoarece cel vechi pare să fi expirat. auto :: $ token = md5 (uniqid () .microtime () rand ()); $ this-> CI-> sesiune-> set_userdata (auto :: $ token_name, auto :: $ token); altfel // Setați-l la variabila locală pentru accesul facil la sine :: $ token = $ this-> CI-> session-> userdata (self :: $ token_name);
Pas cu pas:
FALS
, atunci tokenul nu este încă prezent. Trebuie să ne asigurăm că tokenul a fost trimis și este valabil în cazul în care cererea este a POST
cerere. Mergeți și introduceți următorul cod în dvs. csrf.php
fişier:
/ ** * Validează un token trimis la solicitarea POST. * * @return void * @author Ian Murray * / funcția publică validate_tokens () // Este aceasta o cerere de postare? dacă ($ _SERVER ['REQUEST_METHOD'] == 'POST') // Este setat câmpul token și este valid? $ posted_token = $ this-> CI-> intrare-> post (auto :: $ token_name); dacă $ posted_token === FALSE || $ posted_token! = $ this-> CI-> sesiune-> userdata (self :: $ token_name)) // Cerere nevalidă, trimitere eroare 400. show_error ('Cererea a fost nevalidă. Token-urile nu se potrivesc. ", 400);
POST
cererea, ceea ce înseamnă că, de fapt, a fost depus un formular. Verificăm acest lucru luând o privire la REQUEST_METHOD
în cadrul $ _SERVER
super global. $ This-> CI-> introducere de text> post (auto :: $ token_name)
este FALS
, atunci tokenul nu a fost niciodată postat. Aceasta este partea distractivă! Trebuie să injectăm token-urile în toate formele. Pentru a face viața mai ușoară pentru noi înșine, vom plasa două meta-tag-uri în cadrul nostru (Rails-like). În acest fel, putem include și tokenul în cererile AJAX.
Adăugați următorul cod la adresa dvs. csrf.php
fişier:
/ ** * Aceasta injectează etichetele ascunse pe toate formele POST cu jetonul csrf. * De asemenea, injectează meta-anteturile în de ieșire (dacă există) pentru acces ușor * din cadrele JS. * * @return void * @inutorul Ian Murray * / funcția publică inject_tokens () $ output = $ this-> CI-> output-> get_output (); // Injectați în formă $ output = preg_replace ('/ (<(form|FORM)[^>] * (metoda | METODA) = "(post | POST)" [^>] *>) / ',' $ 0', $ output); // Injectați în $ output = preg_replace ('/ (<\/head>) / ','". "\ n". '". "\ n". '$ 0', ieșire $); $ This-> CI-> output -> _ afișare ($ output);
display_override
cârlig, trebuie să preluăm ieșirea generată de la CodeIgniter. Noi facem asta folosind $ This-> CI-> bază de obiective> get_output ()
metodă. POST
. antet
(daca prezentul). Acest lucru este simplu, deoarece eticheta capului de închidere ar trebui să fie prezentă doar o dată pe fișier. display_override
cârlig, metoda implicită de afișare a vizualizării nu va fi apelată. Această metodă include tot felul de lucruri pe care nu ar trebui să le facem - doar pentru a injecta un cod. Apelarea la noi înșine rezolvă acest lucru. Nu în ultimul rând, trebuie să creăm cârligele înșiși - așa că metodele noastre sunt chemate. Inserați următorul cod în Sistem / aplicație / config / hooks.php
fişier:
// // Cârlige de protecție CSRF, nu atingeți acestea decât dacă știți ce faceți //. ORDERUL ACESTEI HOOKS ESTE IMPORTANT EXTREMEL! // ACEASTĂ trebuie să mergeți primul în post -controller_constructor LISTA HOOK. $ hook ['post_controller_constructor'] [] = array (// Mind "[]", acesta nu este singurul post_controller_constructor cârlig 'class' => 'CSRF_Protection', 'function' => 'validate_tokens' > 'csrf.php', 'filepath' => 'cârlige'); // generează tokenul (TREBUIE SĂ FACĂ DUPĂ VALIDARE AU FOST FĂCUT, DUPĂ CĂ CONTROLLERUL ESTE EXECUTAT, ALTUL UTILIZATOR NU ESTE ACCESORIAT LA UN FORMULAR VALUTAT PENTRU FORMULARI VAMALE). $ hook ['post_controller_constructor'] [] = array (// Mind "[]", acesta nu este singurul post_controller_constructor cârlig 'class' => 'CSRF_Protection', ' > 'csrf.php', 'filepath' => 'cârlige'); // Aceasta injectează jetoanele pe toate formele $ hook ['display_override'] = array ('class' => 'CSRF_Protection', 'function' => 'inject_tokens', 'filename' => 'csrf.php' => "cârlige");
post_controller_constructor
cârlig, așa că trebuie să adăugăm acele paranteze ("[]
"). Consultați documentația privind cârligele CodeIgniter pentru mai multe informații. post_controller_constructor
, generează tokenul în cazul în care nu a fost încă generat. formă
si antet
. Cu un efort minim, am construit o bibliotecă destul de bună pentru noi înșine.
Puteți utiliza această bibliotecă în orice proiect și vă va proteja automat site-ul împotriva CSRF.
Dacă doriți să contribuiți la acest mic proiect, vă rugăm să lăsați un comentariu de mai jos sau să dezactivați proiectul pe GitHub. Alternativ, începând cu CodeIgniter v2.0, protecția împotriva atacurilor CSRF este acum integrată în cadrul!