Fixarea sesiunii - Session fixation
În securitatea rețelei de calculatoare, atacurile de fixare a sesiunii încearcă să exploateze vulnerabilitatea unui sistem care permite unei persoane să fixeze (să găsească sau să seteze) identificatorul de sesiune al altei persoane . Majoritatea atacurilor de fixare a sesiunilor sunt bazate pe web și majoritatea se bazează pe identificatorii de sesiune care sunt acceptați de la adrese URL ( șir de interogare ) sau date POST.
Scenarii de atac
Alice are un cont la bancăhttp://unsafe.example.com/
Mallory intenționează să țintească banii Alicei de la banca ei.
Alice are un nivel rezonabil de încredere în Mallory și va vizita linkurile pe care Mallory i le trimite.
Un scenariu simplu de atac
Scenariu simplu:
- Mallory a stabilit că
http://unsafe.example.com/acceptă orice identificator de sesiune, acceptă identificatorii de sesiune din șirurile de interogare și nu are validare de securitate.http://unsafe.example.com/nu este deci sigur. - Mallory îi trimite lui Alice un e-mail: „Hei, verificați acest lucru, există o nouă funcție de rezumat cont nou pe banca noastră
http://unsafe.example.com/?SID=I_WILL_KNOW_THE_SID”. Mallory încearcă să fixeze SID-ul laI_WILL_KNOW_THE_SID. - Alice este interesată și vizitează
http://unsafe.example.com/?SID=I_WILL_KNOW_THE_SID. Apare ecranul obișnuit de conectare, iar Alice se conectează. - Mallory vizitează
http://unsafe.example.com/?SID=I_WILL_KNOW_THE_SIDși are acum acces nelimitat la contul lui Alice.
Atacă folosind SID generat de server
O concepție greșită este că, dacă un server acceptă numai identificatorii de sesiune generați de server, este ferit de fixare. Acest lucru este fals .
Scenariu:
- Mallory vizitează
http://vulnerable.example.com/și verifică care SID este returnat. De exemplu, serverul poate răspunde:Set-Cookie: SID=0D6441FEA4496C2. - Mallory este acum în stare să îi trimită lui Alice un e-mail: „Vedeți această nouă funcție interesantă de pe banca noastră
http://vulnerable.example.com/?SID=0D6441FEA4496C2.” - Alice se conectează, cu identificatorul de sesiune fixat
SID=0D6441FEA4496C2. - Mallory vizitează
http://vulnerable.example.com/?SID=0D6441FEA4496C2și are acum acces nelimitat la contul lui Alice.
Atacă folosind cookie-uri cu subdomenii încrucișate
Acest tip de atac este similar cu un atac pe site-uri cross-site, cu excepția faptului că nu se bazează pe vulnerabilitatea browserului utilizatorului. Mai degrabă, se bazează pe faptul că cookie-urile wildcard pot fi setate de un subdomeniu și că aceste cookie-uri pot afecta alte subdomenii.
Scenariu:
- Un site web
www.example.comdistribuie subdomenii unor terțe părți care nu au încredere - O astfel de petrecere, Mallory, care controlează acum
evil.example.com, îl atrage pe Alice pe site-ul său - O vizită pentru a
evil.example.comseta un cookie de sesiune cu domeniul de.example.compe browserul Alice - Când Alice va vizita
www.example.comacest cookie va fi trimis împreună cu solicitarea, iar Alice va avea sesiunea specificată de cookie-ul lui Mallory. - Dacă Alice se conectează acum, Mallory își poate folosi contul.
Când acest atac este finalizat, Mallory poate avea acces la www.example.comAlice.
Nu este esențial ca un utilizator să se autentifice pentru a exploata atacurile de fixare a sesiunii și, deși aceste atacuri neautentificate nu sunt constrânse la atacuri cookie inter-sub-domeniu, implicațiile atacurilor sub-domeniu sunt relevante pentru aceste scenarii neautentificate. De exemplu, Mallory poate furniza o adresă URL de pe site-ul lor malefic, fixând o sesiune într-un scenariu neautentificat și poate folosi aceste tehnici pentru a-și exploata ținta. Aceasta include scenarii care exploatează atât scenariile neautentificate (de exemplu, formulare sau înregistrare), cât și capacitatea de a alimenta utilizatorul o sesiune stabilită pentru a ocoli complet datele de autentificare.
Luați în considerare, de exemplu, faptul că Mallory poate crea un utilizator A1ice pe www.example.com și să se conecteze la acel utilizator pentru a capta un identificator de sesiune curent și valid. Mallory îl captează apoi pe Alice cu o adresă URL de la evil.example.com care fixează acel cookie de sesiune în browserul Alice (așa cum este descris mai sus) și redirecționează către www.example.com pentru finalizarea unei anumite tranzacții (sau, de fapt, pentru o utilizare mai largă). Mallory este astfel capabil să fantomeze sesiunea de la autentificarea lor originală, răzuind date și executând operațiuni ca „A1ice” pe „www.example.com”. Dacă Alice a fost înșelată cu succes și și-a salvat cardul de credit în cont, Mallory ar putea face apoi achiziții folosind acel card.
Contramăsuri
Nu acceptați identificatorii de sesiune din variabilele GET / POST
Identificatorii de sesiune din URL (șir de interogare, variabile GET) sau variabile POST nu sunt recomandați deoarece simplifică acest atac - este ușor să creați legături sau formulare care setează variabile GET / POST.
- SID-ul este difuzat către alte persoane, deoarece utilizatorii tăie și lipesc „linkuri interesante” din bara de adrese în chat-uri, forumuri, comunități etc.
- SID-ul este stocat în multe locuri (jurnal istoric browser, jurnal server web, jurnale proxy, ...)
Notă: cookie-urile sunt partajate între file și ferestrele pop-up ale browserului. Dacă sistemul dvs. trebuie să fie accesat cu același domeniu (www.example.com/?code=site1 și www.example.com/?code=site2), cookie-urile pot intra în conflict între file.
Este posibil să fie necesar să trimiteți identificatorul sesiunii pe adresa URL pentru a depăși această limitare. Dacă este posibil, utilizați site1.example.com sau site2.example.com, astfel încât să nu existe conflicte de domeniu în cookie-uri. Acest lucru poate atrage costuri cu certificate SSL suplimentare.
Acest comportament poate fi văzut pe multe site-uri deschizând o altă filă și încercând să facă rezultate de căutare cot la cot. Una dintre sesiuni va deveni inutilizabilă.
Cea mai bună soluție: confirmarea identității
Acest atac poate fi în mare măsură evitat prin schimbarea ID-ului sesiunii atunci când utilizatorii se conectează. Dacă fiecare cerere specifică unui utilizator necesită autentificarea utilizatorului cu („conectat”) site-ul, un atacator ar trebui să cunoască ID-ul victimei sesiune de logare. Cu toate acestea, atunci când victima vizitează linkul cu ID-ul sesiunii fixe, va trebui să se conecteze la contul lor pentru a face orice „important” ca ei înșiși. În acest moment, ID-ul sesiunii lor se va schimba, iar atacatorul nu va putea face nimic „important” cu ID-ul sesiunii anonim.
O tehnică similară poate fi utilizată pentru a rezolva problema de phishing . Dacă utilizatorul își protejează contul cu două parole, atunci acesta poate fi rezolvat într-o mare măsură.
Această tehnică este utilă și împotriva atacurilor de falsificare a cererilor între site-uri .
Soluție: Stocați identificatorii de sesiune în cookie-uri HTTP
Identificatorul de sesiune pe majoritatea sistemelor moderne este stocat în mod implicit într-un cookie HTTP , care are un nivel moderat de securitate atâta timp cât sistemul de sesiune nu ține cont de valorile GET / POST. Cu toate acestea, această soluție este vulnerabilă la falsificarea cererilor între site-uri și nu îndeplinește cerința apatridiei REST .
Soluție: utilizați identificatorul de sesiune SSL / TLS
Când activați securitatea HTTPS , unele sisteme permit aplicațiilor să obțină identificatorul de sesiune SSL / TLS . Utilizarea identificatorului de sesiune SSL / TLS este foarte sigură, dar multe limbaje de dezvoltare web nu oferă funcționalitate încorporată robustă pentru acest lucru.
Regenerați SID la fiecare cerere
O contramăsură împotriva fixării sesiunii este generarea unui nou identificator de sesiune (SID) la fiecare cerere. Dacă se face acest lucru, chiar dacă un atacator poate păcăli un utilizator să accepte un SID cunoscut, SID va fi invalid atunci când atacatorul încearcă să reutilizeze SID-ul. Implementarea unui astfel de sistem este simplă, după cum demonstrează următoarele:
- Obțineți identificatorul de sesiune anterior
OLD_SIDdin solicitarea HTTP. - Dacă
OLD_SIDeste nul, gol sau fără sesiune cu SID =OLD_SIDexistă, creați o nouă sesiune. - Generați un identificator de sesiune nou
NEW_SIDcu un generator de numere aleatorii sigure. - Să sesiunea să fie identificată de SID =
NEW_SID(și nu mai de SID =OLD_SID) - Transmiteți un nou SID către client.
Exemplu:
Dacă Mallory o păcălește cu succes pe Alice în vizită http://victim.example.com/?SID=I_KNOW_THE_SID, această solicitare HTTP este trimisă la victim.example.com:
GET /?SID=I_KNOW_THE_SID HTTP/1.1
Host: victim.example.com
victim.example.comacceptă SID=I_KNOW_THE_SID, ceea ce în mod normal ar fi rău. Cu toate acestea, victim.example.comeste sigur, deoarece efectuează regenerarea sesiunii. victim.example.comprimește următorul răspuns:
HTTP/1.1 200 OK
Set-Cookie: SID=3134998145AB331F
Alice va folosi acum ceea SID=3134998145AB331Fce este necunoscut lui Mallory și SID=I_KNOW_THE_SIDeste invalid. Mallory nu reușește astfel în încercarea de fixare a sesiunii.
Din păcate, regenerarea sesiunii nu este întotdeauna posibilă. Se știe că apar probleme atunci când sunt utilizate programe terță parte, cum ar fi applet-urile ActiveX sau Java, și când pluginurile browserului comunică cu serverul. Software-ul terț poate provoca deconectarea sau sesiunea ar putea fi împărțită în două sesiuni separate.
Dacă implementarea sesiunilor include transmiterea SID-ului prin variabile GET sau POST, atunci acest lucru ar putea face ca butonul „înapoi” din majoritatea browserelor să fie inutilizabil, deoarece utilizatorul ar folosi apoi un identificator de sesiune mai vechi, nevalid dintr-o solicitare anterioară.
Acceptați numai SID-urile generate de server
O modalitate de îmbunătățire a securității nu este acceptarea identificatorilor de sesiune care nu au fost generați de server. Cu toate acestea, după cum sa menționat mai sus, acest lucru nu împiedică toate atacurile de fixare a sesiunii.
if (!isset($_SESSION['SERVER_GENERATED_SID'])) {
session_destroy(); // Destroy all data in session
}
session_regenerate_id(); // Generate a new session identifier
$_SESSION['SERVER_GENERATED_SID'] = true;
Funcția de deconectare
O funcție de deconectare este utilă, deoarece permite utilizatorilor să indice că o sesiune nu ar trebui să permită cereri suplimentare. Astfel, atacurile pot fi eficiente numai în timp ce o sesiune este activă. Rețineți că următorul cod nu efectuează nicio verificare de falsificare a cererii între site-uri , permițând potențial unui atacator să forțeze utilizatorii să se deconecteze de la aplicația web.
if (logout) {
session_destroy(); // Destroy all data in session
}
Expiră SID-urile vechi
Această apărare este ușor de implementat și are avantajul de a oferi o măsură de protecție împotriva utilizatorilor neautorizați care accesează contul unui utilizator autorizat utilizând o mașină care poate a fost lăsată nesupravegheată.
Stocați o variabilă de sesiune care conține un marcaj de timp al ultimului acces făcut de acel SID. Când acel SID este folosit din nou, comparați ora actuală cu cea stocată în sesiune. Dacă diferența este mai mare decât un număr predefinit, să spunem 5 minute, distrugeți sesiunea. În caz contrar, actualizați variabila de sesiune cu marcajul de timp curent.
Distrugeți sesiunea dacă referentul este suspect
Când vizitați o pagină, majoritatea browserelor web vor seta antetul Referrer - pagina care conținea linkul pe care l-ați urmat pentru a ajunge la această pagină.
Când utilizatorul este conectat la un site care nu este probabil să fie conectat din afara acelui site (de exemplu, site-uri web bancare sau webmail ), iar site-ul nu este tipul de site unde utilizatorii ar rămâne conectați pentru o lungime mare de timp, referentul ar trebui să fie de pe acel site. Orice alt referent trebuie considerat suspect. Cu toate acestea, dacă solicitarea inițială provine dintr-o pagină HTTPS, atunci referrerul va fi eliminat, deci nu puteți depinde de acest sistem de securitate.
De exemplu, http://vulnerable.example.com/ar putea folosi următoarea verificare de securitate:
if (strpos($_SERVER['HTTP_REFERER'], 'http://vulnerable.example.com/') !== 0) {
session_destroy(); // Destroy all data in session
}
session_regenerate_id(); // Generate a new session identifier
Verificați dacă informațiile suplimentare sunt consistente pe toată durata sesiunii
O modalitate de a îmbunătăți în continuare securitatea este să vă asigurați că utilizatorul pare a fi același utilizator final (client). Acest lucru face un pic mai greu să efectuați fixarea sesiunii și alte atacuri.
Pe măsură ce tot mai multe rețele încep să se conformeze RFC 3704 și altor practici anti- spoofing , adresa IP devine mai fiabilă ca identificator de „aceeași sursă”. Prin urmare, securitatea unui site web poate fi îmbunătățită prin verificarea faptului că adresa IP sursă este consecventă pe parcursul unei sesiuni.
Acest lucru ar putea fi realizat în acest mod:
if ($_SERVER['REMOTE_ADDR'] != $_SESSION['PREV_REMOTEADDR']) {
session_destroy(); // Destroy all data in session
}
session_regenerate_id(); // Generate a new session identifier
$_SESSION['PREV_REMOTEADDR'] = $_SERVER['REMOTE_ADDR'];
Cu toate acestea, există câteva puncte de luat în considerare înainte de a utiliza această abordare.
- Mai mulți utilizatori pot partaja o singură adresă IP. Nu este neobișnuit ca o clădire întreagă să partajeze o singură adresă IP folosind NAT .
- Un utilizator poate avea o adresă IP inconsistentă. Acest lucru este valabil pentru utilizatorii din spatele proxy-urilor (cum ar fi clienții AOL ). Este valabil și pentru unii utilizatori de telefonie mobilă / roaming, precum și pentru utilizatorii care se află în spatele conexiunilor de internet echilibrate în sarcină. Utilizatorii cu extensii de confidențialitate IPv6 activate pot modifica oricând și adresele lor de confidențialitate IPv6.
- Nu va funcționa în mod fiabil cu clienții dual stack, deoarece cererile se vor deplasa între IPv4 și IPv6.
- Nu va funcționa în mod fiabil cu utilizatorii de telefonie mobilă, deoarece utilizatorii de telefonie mobilă circulă și între adrese.
Pentru unele site-uri, securitatea adăugată depășește lipsa de comoditate, iar pentru altele nu.
Agent utilizator
Browserele se identifică prin anteturi HTTP „User-Agent”. Acest antet nu se modifică în mod normal în timpul utilizării; ar fi extrem de suspect dacă s-ar întâmpla asta. O aplicație web ar putea utiliza detecția User-Agent în încercarea de a împiedica utilizatorii rău intenționați să fure sesiuni. Cu toate acestea, acest lucru este trivial de ocolit, întrucât un atacator poate captura cu ușurință utilizatorul-agent al victimei cu propriul site și apoi îl poate falsifica în timpul atacului. Acest sistem de securitate propus se bazează pe securitate prin obscuritate .
if ($_SERVER['HTTP_USER_AGENT'] != $_SESSION['PREV_USERAGENT']) {
session_destroy(); // Destroy all data in session
}
session_regenerate_id(); // Generate a new session identifier
$_SESSION['PREV_USERAGENT'] = $_SERVER['HTTP_USER_AGENT'];
Cu toate acestea, există câteva puncte de luat în considerare înainte de a utiliza această abordare.
- Mai mulți utilizatori pot avea același agent de utilizator browser în internet café .
- Mai mulți utilizatori pot avea același browser implicit (de exemplu: Internet Explorer 6 în Windows XP SP3 sau mini browser în telefonul mobil).
Însă agentul utilizatorului se poate modifica legal în câteva cazuri. Următoarele exemple sunt aceleași utilizatori.
- Un smartphone al cărui ecran s-a rotit de la ultima solicitare
Mozilla/5.0 (Linux; U; Android 2.2; en-us; DROID2 Build/VZW) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1 854X480 motorola DROID2Mozilla/5.0 (Linux; U; Android 2.2; en-us; DROID2 Build/VZW) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1 480X854 motorola DROID2
- Mod de compatibilitate Internet Explorer:
Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)
- Un utilizator care accesează un site web printr-un proxy distribuit pe mai multe servere, nu toate fiind actualizate la cea mai recentă versiune a software-ului proxy
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6 (FlipboardProxy/0.0.5; +http://flipboard.com/browserproxy)Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6 (FlipboardProxy/1.1; +http://flipboard.com/browserproxy)
Apărare în profunzime
Apărarea în profunzime este de a combina mai multe contramăsuri. Ideea este simplă: dacă un obstacol este trivial de depășit, mai multe obstacole ar putea fi foarte greu de depășit.
O strategie de apărare în profunzime ar putea implica:
- Activați HTTPS (pentru a vă proteja împotriva altor probleme)
- Configurare corectă (nu acceptați SID-uri externe, setați expirarea etc.)
- Efectuați sesiunea_regenerare, susțineți deconectarea etc.
Recomandările HTTP nu sunt transmise cu SSL / TLS (HTTPS).
Următorul script PHP demonstrează mai multe astfel de contramăsuri combinate într-o manieră de apărare în profunzime:
if (isset($_GET['LOGOUT']) ||
$_SERVER['REMOTE_ADDR'] !== $_SESSION['PREV_REMOTEADDR'] ||
$_SERVER['HTTP_USER_AGENT'] !== $_SESSION['PREV_USERAGENT']) {
session_destroy();
}
session_regenerate_id(); // Generate a new session identifier
$_SESSION['PREV_USERAGENT'] = $_SERVER['HTTP_USER_AGENT'];
$_SESSION['PREV_REMOTEADDR'] = $_SERVER['REMOTE_ADDR'];
Rețineți că acest cod verifică REMOTE_ADDR curent (adresa IP a utilizatorului) și User-agent împotriva REMOTE_ADDR și User-agent ale cererii anterioare. Acest lucru ar putea fi incomod pentru unele site-uri, așa cum am discutat mai sus.
Vezi si
Referințe
linkuri externe
- Colț de securitate: Fixarea sesiunii
- Vulnerabilitate de fixare a sesiunii în aplicații web (PDF)
- Exemplu video de fixare a sesiunii
- Clasificarea amenințărilor consorțiului de securitate a aplicațiilor web