Cele mai frecvente 10 vulnerabilități de securitate web
Publicat: 2022-03-11Pentru prea multe companii, cele mai bune practici de securitate web devin o prioritate numai după ce a avut loc o încălcare a securității. De-a lungul anilor în care am lucrat ca profesionist în securitate IT, am văzut în repetate rânduri cât de obscură poate fi lumea problemelor de securitate a dezvoltării web pentru mulți dintre colegii mei programatori.
O abordare eficientă a amenințărilor de securitate web trebuie, prin definiție, să fie proactivă și defensivă. În acest scop, această postare are scopul de a declanșa o mentalitate de securitate, sperăm că injectând cititorului o doză sănătoasă de paranoia.
În special, acest ghid se concentrează pe 10 capcane comune și semnificative de securitate web de care trebuie să fii conștient, inclusiv recomandări despre cum pot fi atenuate. Accentul este pus pe primele 10 vulnerabilități web identificate de Open Web Application Security Project (OWASP), o organizație internațională non-profit al cărei scop este să îmbunătățească securitatea software-ului pe tot globul.
Un mic primar de securitate cibernetică înainte de a începe – autentificare și autorizare
Când vorbesc cu alți programatori și profesioniști IT, întâmpin adesea confuzii cu privire la distincția dintre autorizare și autentificare. Și, desigur, faptul că abrevierea auth este adesea folosită pentru ambele ajută la agravarea acestei confuzii comune. Această confuzie este atât de comună încât poate că această problemă ar trebui inclusă în această postare ca „Vulnerabilitate web comună zero”.
Deci, înainte de a continua, să clarificăm distincția dintre acești doi termeni:
- Autentificare: Verificarea faptului că o persoană este (sau cel puțin pare a fi) un anumit utilizator, deoarece acesta și-a furnizat corect acreditările de securitate (parolă, răspunsuri la întrebări de securitate, scanare a amprentei etc.).
- Autorizare: Confirmarea faptului că un anumit utilizator are acces la o anumită resursă sau i se acordă permisiunea de a efectua o anumită acțiune.
Altfel spus, autentificarea înseamnă a ști cine este o entitate, în timp ce autorizarea înseamnă a ști ce poate face o entitate dată. Având în vedere acest lucru, să intrăm în primele 10 probleme de securitate pe internet.
Greșeală comună de securitate web nr. 1: defecte de injectare
Defectele de injectare rezultă dintr-un eșec clasic de a filtra intrarea neîncrezătoare. Se poate întâmpla atunci când treceți date nefiltrate către serverul SQL (injecție SQL), către browser (XSS – vom vorbi despre asta mai târziu), către serverul LDAP (injecție LDAP) sau oriunde altundeva. Problema aici este că atacatorul poate injecta comenzi acestor entități, ducând la pierderea datelor și deturnând browserele clienților.
Orice lucru pe care aplicația dvs. primește din surse nesigure trebuie filtrat, de preferință conform unei liste albe. Aproape că nu ar trebui să utilizați niciodată o listă neagră, deoarece este foarte greu și, de obicei, ușor de ocolit. Produsele software antivirus oferă de obicei exemple excelente de liste negre eșuate. Potrivirea modelelor nu funcționează.
Prevenire: vestea bună este că protejarea împotriva injectării este „pur și simplu” o chestiune de filtrare a intrării în mod corespunzător și de a vă gândi dacă o intrare poate fi de încredere. Dar vestea proastă este că toate intrările trebuie filtrate în mod corespunzător, cu excepția cazului în care se poate avea încredere în ele, fără îndoială (dar aici îmi vine în minte zicala „niciodată să nu spui niciodată”.
Într-un sistem cu 1.000 de intrări, de exemplu, filtrarea cu succes a 999 dintre ele nu este suficientă, deoarece aceasta rămâne încă un câmp care poate servi drept vindecare lui Ahile pentru a vă distruge sistemul. Și s-ar putea să credeți că introducerea unui rezultat al unei interogări SQL într-o altă interogare este o idee bună, deoarece baza de date este de încredere, dar dacă perimetrul nu este, intrarea vine indirect de la tipi cu malintențiune. Aceasta se numește Second Order SQL Injection în cazul în care sunteți interesat.
Deoarece filtrarea este destul de greu de făcut corect (cum ar fi cripto), ceea ce vă sfătuiesc de obicei este să vă bazați pe funcțiile de filtrare ale cadrului dvs.: s-a dovedit că funcționează și sunt analizate cu atenție. Dacă nu utilizați cadre, trebuie să vă gândiți bine dacă nu le folosiți într-adevăr are sens în contextul de securitate al serverului. 99% din cazuri nu.
Greșeală comună de securitate web nr. 2: autentificare întreruptă
Aceasta este o colecție de probleme multiple care ar putea apărea în timpul autentificării întrerupte, dar nu toate provin din aceeași cauză principală.
Presupunând că oricine mai dorește să-și ruleze propriul cod de autentificare în 2014 (la ce te gândești?), îl sfătuiesc. Este extrem de greu de făcut corect și există o multitudine de posibile capcane, doar pentru a menționa câteva:
- Adresa URL poate conține ID-ul sesiunii și îl poate transmite altcuiva în antetul referitor.
- Este posibil ca parolele să nu fie criptate nici în stocare, nici în tranzit.
- ID-urile sesiunii ar putea fi previzibile, prin urmare obținerea accesului este trivială.
- Fixarea sesiunii ar putea fi posibilă.
- Deturnarea sesiunii ar putea fi posibilă, timeout-urile nu sunt implementate corect sau folosind HTTP (fără securitate SSL), etc...
Prevenire: Cel mai simplu mod de a evita această vulnerabilitate de securitate web este utilizarea unui cadru. S-ar putea să poți implementa corect acest lucru, dar primul este mult mai ușor. În cazul în care doriți să rulați propriul cod, fiți extrem de paranoic și educați-vă despre care sunt capcanele. Sunt destul de multe.
Greșeală comună de securitate web nr. 3: Cross Site Scripting (XSS)
Acesta este un eșec de igienizare a intrării destul de răspândit (în esență un caz special de greșeală comună #1). Un atacator dă aplicației dvs. web etichete JavaScript la intrare. Când această intrare este returnată utilizatorului neigienizat, browserul utilizatorului o va executa. Poate fi la fel de simplu ca a crea un link și a convinge un utilizator să facă clic pe el, sau poate fi ceva mult mai sinistru. La încărcarea paginii, scriptul rulează și, de exemplu, poate fi folosit pentru a posta cookie-urile către atacator.
Prevenire: Există o soluție simplă de securitate web: nu returnați etichetele HTML clientului. Acest lucru are avantajul suplimentar de a apăra împotriva injectării HTML, un atac similar prin care atacatorul injectează conținut HTML simplu (cum ar fi imagini sau playere flash invizibile puternice) – nu are un impact ridicat, dar cu siguranță enervant („te rog să oprești!”). De obicei, soluția este pur și simplu convertirea tuturor entităților HTML, astfel încât <script>
să fie returnat ca <script>
. Cealaltă metodă de dezinfectare folosită des este folosirea expresiilor regulate pentru a îndepărta etichetele HTML folosind expresii regulate pe <
și >
, dar acest lucru este periculos, deoarece multe browsere vor interpreta HTML foarte deteriorat. Mai bine să convertiți toate personajele în omologii lor scăpați.
Greșeală comună de securitate web #4: Referințe nesigure la obiecte directe
Acesta este un caz clasic de încredere în intrarea utilizatorului și de a plăti prețul unei vulnerabilități de securitate care rezultă. O referință directă la obiect înseamnă că un obiect intern, cum ar fi un fișier sau o cheie de bază de date, este expus utilizatorului. Problema cu aceasta este că atacatorul poate furniza această referință și, dacă autorizarea fie nu este aplicată (sau este ruptă), atacatorul poate accesa sau poate face lucruri pentru care ar trebui să fie excluse.
De exemplu, codul are un modul download.php
care citește și permite utilizatorului să descarce fișiere, folosind un parametru CGI pentru a specifica numele fișierului (de exemplu, download.php?file=something.txt
). Fie din greșeală, fie din lene, dezvoltatorul a omis autorizarea din cod. Atacatorul poate folosi acum acest lucru pentru a descărca orice fișiere de sistem la care are acces utilizatorul care rulează PHP, cum ar fi codul aplicației în sine sau alte date rămase pe server, cum ar fi copii de rezervă. Uh-oh.
Un alt exemplu obișnuit de vulnerabilitate este o funcție de resetare a parolei care se bazează pe intrarea utilizatorului pentru a determina a cui parolă o resetăm. După ce face clic pe adresa URL validă, un atacator poate modifica câmpul de username
de utilizator din URL pentru a spune ceva de genul „admin”.
De altfel, ambele exemple sunt lucruri pe care eu le-am văzut apărând adesea „în sălbăticie”.
Prevenire: Efectuați autorizarea utilizatorului în mod corespunzător și consecvent și includeți opțiunile pe lista albă. Totuși, de cele mai multe ori, întreaga problemă poate fi evitată prin stocarea internă a datelor și fără a te baza pe acestea să fie transmise de la client prin parametrii CGI. Variabilele de sesiune din majoritatea cadrelor sunt potrivite pentru acest scop.
Greșeală comună de securitate web #5: Configurare greșită a securității
Din experiența mea, serverele web și aplicațiile care au fost configurate greșit sunt mult mai frecvente decât cele care au fost configurate corect. Poate asta pentru că nu lipsesc modalitățile de a da peste cap. Cateva exemple:
- Rularea aplicației cu depanarea activată în producție.
- Având listarea directoarelor activată pe server, care furnizează informații valoroase.
- Rulează software învechit (gândiți-vă la pluginuri WordPress, vechiul PhpMyAdmin).
- Aveți servicii inutile care rulează pe mașină.
- Nu se schimbă cheile și parolele implicite. (Se întâmplă mult mai des decât ai crede!)
- Dezvăluirea informațiilor de tratare a erorilor către atacatori, cum ar fi urmele stivei.
Prevenire: aveți un proces bun (de preferință automatizat) de „construire și implementare”, care poate rula teste la implementare. Soluția de configurare greșită a securității a bietului om este cârligele post-comitare, pentru a preveni difuzarea codului cu parole implicite și/sau chestii de dezvoltare încorporate.
Greșeală comună de securitate web nr. 6: expunerea datelor sensibile
Această vulnerabilitate de securitate web se referă la protecția cripto și a resurselor. Datele sensibile ar trebui să fie criptate în orice moment, inclusiv în tranzit și în repaus. Fara exceptii. Informațiile cărților de credit și parolele utilizatorului nu trebuie să călătorească niciodată sau să fie stocate necriptate, iar parolele ar trebui să fie întotdeauna hashing. Evident, algoritmul de cripto/hashing nu trebuie să fie unul slab – atunci când aveți îndoieli, standardele de securitate web recomandă AES (256 de biți și mai mult) și RSA (2048 de biți și mai mult).

Și, deși este de la sine înțeles că ID-urile de sesiune și datele sensibile nu ar trebui să călătorească în adresele URL, iar cookie-urile sensibile ar trebui să aibă marcajul de securitate activat, acest lucru este foarte important și nu poate fi subliniat prea mult.
Prevenire:
În tranzit: utilizați HTTPS cu un certificat adecvat și PFS (Perfect Forward Secrecy). Nu acceptați nimic prin conexiuni non-HTTPS. Aveți steag securizat pe cookie-uri.
În depozit: acest lucru este mai greu. În primul rând, trebuie să reduceți expunerea. Dacă nu aveți nevoie de date sensibile, distrugeți-le. Datele pe care nu le aveți nu pot fi furate. Nu stocați niciodată informații despre cardul de credit, deoarece probabil că nu doriți să aveți de-a face cu respectarea PCI. Înscrieți-vă la un procesor de plăți, cum ar fi Stripe sau Braintree. În al doilea rând, dacă aveți date sensibile de care aveți nevoie, stocați-le criptate și asigurați-vă că toate parolele sunt hashing. Pentru hashing, se recomandă utilizarea bcrypt. Dacă nu folosiți bcrypt, educați-vă despre sărare și mesele curcubeu.
Și cu riscul de a afirma ceea ce este evident, nu stocați cheile de criptare lângă datele protejate . Este ca și cum ai depozita bicicleta cu un lacăt care are cheia în ea. Protejați-vă copiile de rezervă cu criptare și păstrați-vă cheile foarte private. Și bineînțeles, nu pierdeți cheile!
Greșeală comună de securitate web #7: lipsește controlul accesului la nivel de funcție
Acesta este pur și simplu un eșec de autorizare. Înseamnă că atunci când o funcție este apelată pe server, nu a fost efectuată autorizarea corespunzătoare. De multe ori, dezvoltatorii se bazează pe faptul că partea de server a generat interfața de utilizare și cred că funcționalitatea care nu este furnizată de server nu poate fi accesată de client. Nu este atât de simplu, deoarece un atacator poate oricând să falsifice solicitări la funcționalitatea „ascunsă” și nu va fi descurajat de faptul că interfața de utilizare nu face această funcționalitate ușor accesibilă. Imaginați-vă că există un panou /admin
, iar butonul este prezent în interfața de utilizare numai dacă utilizatorul este de fapt un administrator. Nimic nu împiedică un atacator să descopere această funcționalitate și să o utilizeze greșit dacă lipsește autorizarea.
Prevenire: Pe partea de server, autorizarea trebuie făcută întotdeauna . Da întotdeauna. Nicio excepție sau vulnerabilitate nu va duce la probleme serioase.
Greșeală comună de securitate web nr. 8: falsificarea cererii pe site-uri (CSRF)
Acesta este un exemplu frumos de atac adjunct confuz prin care browserul este păcălit de o altă parte pentru a-și folosi abuziv autoritatea. Un site terță parte, de exemplu, poate face ca browserul utilizatorului să utilizeze greșit autoritatea sa de a face ceva pentru atacator.
În cazul CSRF, un site terță parte emite solicitări către site-ul țintă (de exemplu, banca dvs.) folosind browser-ul dvs. cu cookie-uri / sesiune. Dacă sunteți conectat într-o singură filă de pe pagina de pornire a băncii dvs., de exemplu, și sunt vulnerabile la acest atac, o altă filă poate face ca browserul dvs. să-și folosească greșit acreditările în numele atacatorului, ceea ce duce la o problemă confuză a adjunctului. Adjunctul este browserul care își folosește abuziv autoritatea (cookie-uri de sesiune) pentru a face ceva ce atacatorul îi cere să facă.
Luați în considerare acest exemplu:
Atacatorul Alice vrea să ușureze portofelul țintei lui Todd transferându-i o parte din banii lui. Banca lui Todd este vulnerabilă la CSRF. Pentru a trimite bani, Todd trebuie să acceseze următoarea adresă URL:
http://example.com/app/transferFunds?amount=1500&destinationAccount=4673243243
După deschiderea acestei adrese URL, Todd îi este prezentată o pagină de succes și transferul este finalizat. Alice mai știe că Todd vizitează frecvent un site sub controlul ei la blog.aliceisawesome.com, unde plasează următorul fragment:
<img src=http://example.com/app/transferFunds?amount=1500&destinationAccount=4673243243 width=0 height=0 />
După ce vizitează site-ul lui Alice, browserul lui Todd crede că Alice trimite la o imagine și emite automat o solicitare HTTP GET pentru a prelua imaginea, dar aceasta îi dă instrucțiuni băncii lui Todd să transfere 1500 USD către Alice.
De altfel, pe lângă demonstrarea vulnerabilității CSRF, acest exemplu demonstrează și modificarea stării serverului cu o solicitare HTTP GET idempotent, care este ea însăși o vulnerabilitate gravă. Solicitările HTTP GET trebuie să fie idempotente (sigure), ceea ce înseamnă că nu pot modifica resursa care este accesată. Nu utilizați niciodată, niciodată, niciodată metode idempotente pentru a schimba starea serverului.
Fapt amuzant: CSRF este, de asemenea, metoda folosită de oameni pentru umplerea cookie-urilor în trecut, până când afiliații au devenit mai înțelepți.
Prevenire: stocați un token secret într-un câmp de formular ascuns care este inaccesibil de pe site-ul terțului. Desigur, trebuie să verificați întotdeauna acest câmp ascuns. Unele site-uri vă cer parola și atunci când modifică setările sensibile (cum ar fi e-mailul de reamintire a parolei, de exemplu), deși aș bănui că acest lucru este acolo pentru a preveni utilizarea greșită a sesiunilor abandonate (într-un internet cafe, de exemplu).
Greșeală comună de securitate web #9: Utilizarea componentelor cu vulnerabilități cunoscute
Titlul spune totul. Aș clasifica din nou acest lucru ca fiind mai mult o problemă de întreținere/implementare. Înainte de a încorpora codul nou, faceți câteva cercetări, eventual câteva auditări. Utilizarea codului pe care l-ați primit de la o persoană aleatorie pe GitHub sau pe un forum poate fi foarte convenabilă, dar nu este lipsită de riscul unei vulnerabilități serioase de securitate web.
Am văzut multe cazuri, de exemplu, în care site-uri au fost deținute (adică, în care un străin câștigă acces administrativ la un sistem), nu pentru că programatorii au fost proști, ci pentru că un software terță parte a rămas nepattched ani de zile în producție. Acest lucru se întâmplă tot timpul cu pluginurile WordPress, de exemplu. Dacă credeți că nu vă vor găsi instalarea ascunsă phpmyadmin
, permiteți-mi să vă prezint dirbuster.
Lecția aici este că dezvoltarea software-ului nu se termină atunci când aplicația este implementată. Trebuie să existe documentație, teste și planuri cu privire la modul de întreținere și menținere actualizată, mai ales dacă conține componente terțe sau open source.
Prevenire:
Fiți precauți. Dincolo de a fi, evident, prudență atunci când utilizați astfel de componente, nu fiți un codificator copy-paste. Inspectați cu atenție fragmentul de cod pe care urmează să îl introduceți în software-ul dvs., deoarece ar putea fi spart fără reparații (sau, în unele cazuri, în mod intenționat rău intenționat - atacurile de securitate web sunt uneori invitate fără să vrea în acest fel).
Sa fii la curent. Asigurați-vă că utilizați cele mai recente versiuni pentru tot ceea ce aveți încredere și aveți un plan pentru a le actualiza în mod regulat. Cel puțin abonați-vă la un buletin informativ cu noile vulnerabilități de securitate referitoare la produs.
Greșeală comună de securitate web #10: redirecționări și redirecționări nevalidate
Aceasta este încă o dată o problemă de filtrare a intrărilor. Să presupunem că site-ul țintă are un modul redirect.php
care ia un URL ca parametru GET
. Manipularea parametrului poate crea o adresă URL pe targetsite.com
care redirecționează browserul către malwareinstall.com
. Când utilizatorul vede linkul, va vedea targetsite.com/blahblahblah
pe care utilizatorul îl consideră de încredere și pe care îl poate face în siguranță. Nu știu ei că acest lucru le va transfera într-o pagină de drop-uri malware (sau orice altă pagină rău intenționată). Ca alternativă, atacatorul poate redirecționa browserul către targetsite.com/deleteprofile?confirm=1
.
Este demn de menționat că introducerea unei intrări neigienizate definite de utilizator într-un antet HTTP poate duce la injectarea antetului, ceea ce este destul de rău.
Prevenire: Opțiunile includ:
- Nu faceți deloc redirecționări (acestea sunt rareori necesare).
- Aveți o listă statică de locații valide către care să vă redirecționați.
- Lista albă a parametrului definit de utilizator, dar acest lucru poate fi dificil.
Epilog
Sper că am reușit să vă gâdil puțin creierul cu această postare și să introduc o doză sănătoasă de paranoia și conștientizarea vulnerabilității securității site-ului web.
Principala concluzie aici este că practicile software vechi există dintr-un motiv și ceea ce se aplica pe vremuri pentru depășirile de buffer, se aplică și astăzi pentru șirurile murate în Python. Protocoalele de securitate vă ajută să scrieți (mai multe) programe corecte, la care ar trebui să aspire toți programatorii.
Vă rugăm să utilizați aceste cunoștințe în mod responsabil și să nu testați pagini fără permisiune!
Pentru mai multe informații și mai multe atacuri specifice serverului, aruncați o privire la: https://www.owasp.org/index.php/Category:Attack.
Feedback-ul despre această postare și sfaturile sale de atenuare sunt binevenite și apreciate. Sunt planificate postări viitoare legate, în special în ceea ce privește problema vulnerabilităților de securitate IT distribuite de denial-of-service (DDoS) și vechi (nu web). Dacă aveți o solicitare specifică despre ce fel de protecție web să scrieți, vă rugăm să nu ezitați să mă contactați direct la [email protected].
Iată siguranța site-ului! Noroc.
- Tutorial JSON Web Token: Un exemplu în Laravel și AngularJS
- Performanță și eficiență: Lucrul cu HTTP/3