Jurnalul modificărilor: Proiectul OWASP Top 10
Publicat: 2022-03-11Aplicațiile web au explodat în complexitate în ultimul deceniu. Au evoluat de la simple containere pentru formulare de contact și sondaje în aplicații complete. Le putem compara cu aplicațiile desktop grele, atât ca dimensiune, cât și ca performanță. Odată cu o creștere semnificativă a complexității și un număr tot mai mare de aplicații bogate în funcții, a devenit o necesitate să investim mult timp și grijă pentru a face toate componentele aplicației cât mai sigure posibil. Creșterea masivă a utilizatorilor de internet a făcut și mai importantă abordarea problemei protecției datelor și a utilizatorilor aplicațiilor. Există o mare cantitate de amenințări care încearcă să se strecoare și să provoace dureri de cap severe tuturor celor implicați.
În 2001, a intrat în scenă o nouă organizație. Scopul său a fost să lupte împotriva problemelor de securitate care afectează site-urile web și aplicațiile. A fost numit în mod corespunzător Proiectul de securitate a aplicațiilor web deschise (OWASP). În prezent, publică resurse, organizează conferințe și propune standarde privind securitatea web și a aplicațiilor. Un standard de facto pentru securitatea aplicațiilor web este OWASP Top Ten Project. Enumeră cele mai răspândite zece amenințări de securitate. Factorii influenți în a decide ce intră au fost o cantitate mare de date și feedbackul comunității. La sfârșitul anului 2017, a avut loc o actualizare a proiectului. Câteva probleme noi critice pentru o mulțime de aplicații web moderne și-au luat locul, în timp ce unele au scăpat de pe listă.
Acest articol completează lista originală și ilustrează cele mai recente modificări aduse listei. Descrie amenințările, încearcă să ofere exemple clare pentru o înțelegere mai ușoară și propune modalități de combatere a amenințărilor de securitate.
Probleme eliminate din Lista OWASP Top 10
Înainte de actualizarea din 2017, lista din 2013 era cea mai recentă. Având în vedere schimbările în modul în care aplicațiile web sunt acum construite și consumate, a avut sens să facem doar o revizuire amănunțită. Microserviciile își iau partea din plăcintă, iar noile cadre interesante și strălucitoare înlocuiesc echipamentele de luptă cu cod vanilie. Aceste fapte înseamnă că unele dintre amenințările enumerate anterior au fost eliminate, iar unele noi le-au luat locul.
Ne vom asigura că ne reîmprospătăm memoria despre problemele uitate de mult în acest articol, precum și vom prezenta noii lupi răi. A învăța despre istorie este singura modalitate sigură de a nu repeta aceleași greșeli.
Solicitare falsificare între site-uri
Falsificarea cererilor încrucișate (CSRF) este unul dintre „perdanții” în ultima iterație a proiectului. A dispărut deoarece multe cadre web moderne includ mecanisme de apărare CSRF. Probabilitatea de a vă expune aplicațiile la amenințare scade astfel rapid.
Indiferent dacă CSRF iese din listă, este totuși bine să ne reîmprospătăm memoria. Să ne asigurăm că nu se întoarce mai puternic ca niciodată.
În esență, CSRF este un exploit care simte o bombă de fum. Un atacator păcălește un utilizator care nu bănuiește să execute o cerere sau o acțiune nedorită într-o aplicație web. Mai simplu spus, un atacator își forțează victima să trimită o cerere către o aplicație terță parte, iar victima nu știe că cererea a fost trimisă vreodată. Solicitarea poate fi o solicitare HTTP GET pentru a prelua o resursă, sau chiar mai rău, o solicitare HTTP POST care modifică o resursă aflată sub controlul victimei. În timpul atacului, victima crede că totul este în regulă, cel mai adesea fără să observe că se întâmplă ceva în fundal. După ce aerul se limpezește, daunele sunt făcute sau ceva lipsește și nimeni nu știe ce s-a întâmplat.
Autentificarea anterioară de succes a utilizatorului în cadrul aplicației țintă este ceea ce permite ca capcana să fie eficientă. Utilizatorul a avut la un moment dat înainte de atac să se conecteze la o aplicație. Aplicația a trimis victimei un cookie pentru a le aminti. Odată ce browser-ul web trimite cererea rău intenționată, cookie-ul este trimis automat împreună cu orice sarcină utilă potențială și aplicația nu se opune la adresarea cererii unui utilizator pe care îl cunoaște deja.
Unul dintre cele mai faimoase exemple este păcălirea unui utilizator pentru a transfera bani din contul său în cel controlat de un atacator. Un utilizator se conectează la un sistem e-banking pentru a-și verifica soldul contului. După aceea, vizitează un forum online pentru a verifica recenziile unui nou telefon mobil. Un atacator, care pescuiește cu dinamită, postează o recenzie care include o imagine cu un hyperlink de imagine aparent rupt. În loc de un hyperlink real, atacatorul folosește un hyperlink pe care sistemul e-banking îl folosește intern pentru a transfera bani din contul A în contul B: https://payments.dummybank.com?receiver=attacker&amount=100
. Sistemul bancar face din utilizatorul autentificat expeditorul, iar valoarea din parametrul „destinatar” destinatarul fondurilor. Desigur, atacatorul își specifică contul offshore drept destinatar.
Deoarece browserul încarcă automat imaginile la randarea paginii, solicitarea are loc în fundal. Dacă sistemul de plată al băncii implementează transferuri de bani folosind o solicitare HTTP GET, nimic nu împiedică producerea dezastrului. Rețineți că exemplul este simplu și, cel mai probabil, transferurile nu sunt gestionate prin HTTP GET. Cu toate acestea, atacatorul poate, cu doar puțin mai multă dificultate, să reușească să schimbe atributul „acțiune” în formularul de postare a mesajelor HTML al forumului. Browserul trimite apoi cererea către sistemul de plată al băncii, în locul back-end-ului forumului.
Furtul de bani este doar unul dintre numeroasele exemple care există. Modificarea adreselor de e-mail ale utilizatorilor sau efectuarea de achiziții neintenționate se încadrează și în această categorie. După cum se întâmplă adesea, ingineria socială și unele cunoștințe tehnice sunt o pârghie eficientă împotriva unei greșeli de inginerie software.
Când vă proiectați sistemele, țineți cont de următoarele:
- Nu utilizați cereri HTTP GET pentru încapsularea acțiunilor care modifică o resursă. Ar trebui să utilizați aceste solicitări numai pentru a prelua informații. Amintiți-vă, regula generală este de a face cererile GET idempotente.
- Atunci când transferați date intern folosind solicitări HTTP POST, aveți tendința de a trimite datele în JSON, XML sau alt format decât codificarea parametrilor ca șir de interogare. Utilizarea unui format de date non-trivial reduce pericolul ca cineva să creeze un formular HTML fals care va trimite datele către serviciul dumneavoastră.
- Asigurați - vă că creați și includeți un simbol unic și imprevizibil în formularele dvs. HTML. Aceste jetoane ar trebui să fie, de asemenea, unice pentru fiecare cerere. Verificarea prezenței și corectitudinii unor astfel de jetoane va reduce riscurile de apariție a amenințărilor. Pentru a afla simbolul și a-l folosi în cererile lor false, atacatorii ar trebui să vă acceseze sistemul și să ia un jeton direct de acolo. Deoarece jetoanele sunt o singură dată, nu le pot reutiliza în codul rău intenționat.
Această vulnerabilitate are un efect și mai rău atunci când este cuplată cu cross-site scripting (XSS). Dacă un atacator poate injecta cod rău intenționat într-un site sau aplicație preferată, sfera atacului devine mult mai semnificativă și mai periculoasă. Și mai critic, atacatorii pot ocoli unele dintre mecanismele de protecție împotriva CSRF dacă atacurile XSS sunt posibile.
Țineți minte că CSRF nu a dispărut, pur și simplu nu este atât de comun ca înainte.
Redirecționări și redirecționări nevalidate
O mulțime de aplicații, după terminarea unei acțiuni, redirecționează sau redirecționează un utilizator către o altă parte a aceleiași sau chiar alte aplicații. De exemplu, conectarea cu succes la o aplicație declanșează o redirecționare către pagina de pornire sau către pagina vizitată inițial de utilizator. Foarte des, destinația face parte din acțiunea formularului sau adresa linkurilor. Dacă componenta care gestionează redirecționarea sau redirecționarea nu se asigură că adresa de destinație este într-adevăr cea care a fost generată de aplicație, apare o potențială amenințare. Aceasta este o vulnerabilitate de securitate numită „redirecționări și redirecționări nevalidate”.
Cele două motive majore pentru care redirecționările și redirecționările nevalidate ar fi vreodată considerate periculoase sunt phishingul și deturnarea acreditărilor. Un atacator poate reuși să modifice locația țintă de redirecționare/redirecționare și să trimită un utilizator către o aplicație rău intenționată aproape imposibil de distins de cea originală. Un utilizator nebănuitor își dezvăluie acreditările și informațiile confidențiale unei terțe părți rău intenționate. Înainte să-și dea seama ce s-a întâmplat, este deja prea târziu.
De exemplu, aplicațiile web implementează foarte des conectarea cu suport pentru redirecționări către ultima pagină vizitată. Pentru a putea face acest lucru cu ușurință, atributul de acțiune al unui formular HTML ar putea arăta ceva de genul http://myapp.example.com/signin?url=http://myapp.example.com/puppies . Sunteți un mare admirator al cățeilor, așa că a avut sens să instalați o extensie de browser care înlocuiește favicon-urile site-ului cu miniaturile cățelușilor dvs. preferați. Din păcate, este o lume care mănâncă câine. Autorul extensiei de browser a decis să profite de dragostea ta necondiționată și să introducă o „funcție” suplimentară. De fiecare dată când vizitați site-ul preferat al fanilor cățeluși, acesta înlocuiește parametrul „url” din atributul de acțiune al formularului cu un link către propriul lor site. Deoarece site-ul arată exact la fel, atunci când oferiți detaliile cărții de credit pentru a cumpăra cărți de joc pentru cățeluși, de fapt finanțați un atacator rău intenționat, nu hobby-ul dvs.
Rezolvarea vulnerabilității implică verificarea locației de destinație, asigurându-vă că este cea dorită. Dacă un cadru sau o bibliotecă realizează redirecționarea sau redirecționarea completă a logicii, este benefic să verificați implementarea și să actualizați codul dacă este necesar. În caz contrar, trebuie să faceți verificări manuale pentru a vă proteja împotriva atacului.
Există mai multe tipuri de verificări pe care le puteți face. Pentru cea mai bună protecție, utilizați o combinație de mai multe abordări în loc să rămâneți doar cu una dintre ele.
- Validați adresa URL de ieșire, asigurându-vă că indică către domeniul pe care îl controlați.
- În loc să folosiți adrese explicite, codificați-le pe front-end și apoi decodați-le și validați-le pe back-end.
- Pregătiți o listă albă de adrese URL de încredere. Permite redirecționări și redirecționări numai către locațiile din lista albă. Preferați această abordare pentru a menține o listă neagră. Listele negre sunt de obicei pline cu elemente noi numai atunci când se întâmplă ceva rău. Listele albe sunt mai restrictive.
- Folosiți o abordare folosită de LinkedIn și de alte aplicații: prezentați utilizatorilor o pagină care le cere să confirme o redirecționare/redirecționare, arătând clar că părăsesc aplicația dvs.
Probleme îmbinate
Majoritatea problemelor de pe listă pot fi etichetate ca defecte în implementare, fie din cauza lipsei de cunoștințe, fie din cauza unei investigații insuficient de profunde a potențialelor amenințări. Ambele motive pot fi atribuite lipsei de experiență, iar soluția pentru a le lua în considerare în viitor este ușoară - asigurați-vă doar că învățați mai multe și fiți mai detaliat. Unul deosebit de complicat se bazează pe o combinație a trăsăturii periculoase (dar foarte umane) de a face prea multe presupuneri cuplate cu dificultatea de a dezvolta și întreține sisteme informatice complexe. O vulnerabilitate care se încadrează în această categorie este „controlul accesului întrerupt”.
Controlul accesului spart
O vulnerabilitate este cauzată de lipsa inadecvată sau completă a autorizării și controlului accesului pentru anumite părți ale aplicației. În iterațiile anterioare ale proiectului OWASP Top Ten, au existat două probleme: referințe directe nesigure la obiect și lipsa controlului accesului la nivel de funcție. Ele sunt acum fuzionate într-unul singur datorită asemănării lor.
Referințe directe la obiect
Referințele directe la obiecte sunt adesea folosite în URL-uri pentru a identifica resursele pe care se operează. De exemplu, atunci când un utilizator se conectează, acesta își poate vizita profilul făcând clic pe un link care conține identificatorul profilului său. Dacă același identificator este stocat în baza de date și este folosit pentru a prelua informații de profil, iar aplicația presupune că oamenii pot ajunge la pagina de profil numai printr-o pagină de conectare, schimbarea identificatorului de profil din adresa URL expune informațiile de profil ale altui utilizator.
O aplicație care setează adresa URL a formularului de ștergere a profilului http://myapp.example.com/users/15/delete arată clar că în aplicație există cel puțin alți 14 utilizatori. A afla cum să ajungi la forma de ștergere a altor utilizatori nu este o știință rachetă în acest caz.
Soluția la această problemă este să efectuați verificări de autorizare pentru fiecare resursă fără a presupune că pot fi luate numai anumite căi pentru a ajunge la anumite părți ale aplicației. În plus, eliminarea referințelor directe și utilizarea celor indirecte este un alt pas înainte, deoarece face dificil pentru utilizatorii rău intenționați să-și dea seama cum este creată referința.
În timpul dezvoltării, ca măsură de precauție, notați o diagramă simplă a mașinii de stare. Lăsați stările să reprezinte diferite pagini din aplicația dvs. și tranzițiile pe care utilizatorii le pot întreprinde. Acest lucru face mai ușor să enumerați toate tranzițiile și paginile care necesită o atenție specială.
Lipsește controlul accesului la nivel de funcție
Lipsa controlului accesului la nivel de funcție este foarte asemănătoare cu referințele directe la obiecte nesigure. În acest caz, utilizatorii modifică adresa URL sau alt parametru pentru a încerca să acceseze părțile protejate ale aplicației. Dacă nu există un control adecvat al accesului care examinează nivelurile de acces, un utilizator poate obține acces privilegiat la resursele aplicației sau cel puțin unele cunoștințe despre existența acestora.
Împrumutând din exemplul referințelor directe la obiecte, Dacă o aplicație presupune că un utilizator care vizitează formularul de ștergere este un superutilizator doar pentru că superutilizatorii pot vedea linkul către formularul de ștergere, fără a mai face nicio autorizare, se deschide o defecțiune uriașă de securitate. Contarea pe disponibilitatea unui element UI nu este un control adecvat al accesului.
Problema este rezolvată asigurându-vă întotdeauna că efectuați verificări în toate straturile aplicației dvs. Interfața front-end ar putea să nu fie singura modalitate prin care utilizatorii rău intenționați pot accesa stratul dvs. de domeniu. De asemenea, nu vă bazați pe informațiile transmise de la utilizatori despre nivelurile lor de acces. Efectuați un control adecvat al sesiunii și verificați întotdeauna datele primite. Doar pentru că corpul solicitării spune că utilizatorul este un administrator, nu înseamnă cu adevărat că sunt.
Controlul accesului întrerupt acum combină toate problemele care sunt legate de controlul accesului insuficient, fie la nivel de aplicație, fie la nivel de sistem, cum ar fi o configurare greșită a sistemului de fișiere.
Probleme noi în Lista OWASP Top 10
Apariția noilor framework-uri front-end și adoptarea de noi practici de dezvoltare software au mutat preocupările de securitate către subiecte complet noi. Noile tehnologii au reușit, de asemenea, să rezolve unele probleme comune cu care ne-am ocupat manual înainte. Prin urmare, a devenit benefic să revizuim lista și să o ajustam în consecință la tendințele moderne.
Entități externe XML
Standardul XML oferă o idee puțin cunoscută numită entitate externă, care face parte din definiția tipului de date (DTD) a documentului. Permite autorilor de documente să specifice legături către entități externe care pot fi apoi referite și incluse în documentul principal. Un exemplu foarte simplu ar fi:
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE foo [ <!ELEMENT foo ANY> <!ENTITY bar "baz"> ]> <foo> &bar; </foo>
În timpul parsării, o referință &bar;
este înlocuit cu conținutul de la entitatea definită, producând astfel <foo>baz</foo>
.

Dacă aplicația ar prelua intrare externă și ar include, fără nicio verificare, direct în definiția documentului XML, ar deveni posibilă o gamă largă de scurgeri de date și atacuri.
Lucrul magic este că entitatea nu trebuie să fie un simplu șir - poate fi o referință la un fișier din sistemul de fișiere. Analizatorul XML va fi bucuros să preia conținutul fișierului specificat și să îl includă în răspunsul generat, dezvăluind potențial informații sensibile ale sistemului. După cum este ilustrat de OWASP, ar fi foarte ușor să obțineți informații despre utilizatorii sistemului prin definirea entității ca
<!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
O „trăsătură” deosebit de supărătoare a acestei vulnerabilități este posibilitatea de a executa cu ușurință un atac de tip denial-of-service. O modalitate ușoară de a face acest lucru ar fi să enumerați conținutul unui fișier nesfârșit precum /dev/random
. Celălalt este de a crea o secvență de entități, fiecare făcând referire la cea anterioară de mai multe ori. Acest lucru transformă referința finală într-o rădăcină a unui arbore potențial foarte larg și profund a cărui analiză ar putea epuiza memoria sistemului. Acest atac este chiar cunoscut sub numele de Billion Laughs. După cum se arată pe Wikipedia, sunt definite o serie de entități fictive, producând o oportunitate pentru un atacator de a include un miliard de lols în documentul final.
<?xml version="1.0"?> <!DOCTYPE lolz [ <!ENTITY lol "lol"> <!ELEMENT lolz (#PCDATA)> <!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;"> <!ENTITY lol2 "&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;"> <!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;"> <!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;"> <!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;"> <!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;"> <!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;"> <!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;"> <!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;"> ]> <lolz>&lol9;</lolz>
Prevenirea exploatărilor de entități externe XML ar putea fi realizată prin utilizarea unui format de date mai puțin complex. JSON este un înlocuitor bun, cu condiția să se ia și unele măsuri de precauție din cauza posibilelor atacuri împotriva acestuia. Actualizarea bibliotecilor XML este o necesitate, împreună cu dezactivarea procesării entităților externe și a DTD. Ca întotdeauna, validați și igienizați datele care provin din surse nesigure înainte de a le utiliza sau de a le include în documente.
Deserializare nesigură
Când scriu cod, dezvoltatorii au puterea de a controla sistemele pe care le dezvoltă folosind codul pe care îl scriu. Cât de minunat ar fi să controlezi comportamentul sistemelor terțe care scriu doar puțin sau chiar deloc cod? Datorită faptului că oamenii nu sunt perfecți și că bibliotecile au defecte, acest lucru este cu siguranță posibil.
Starea și configurația aplicației sunt adesea serializate și stocate. Uneori, browserele servesc ca motoare de stocare dacă datele serializate sunt strâns cuplate cu utilizatorul actual. O aplicație care încearcă să fie inteligentă și să economisească timp de procesare ar putea folosi un cookie pentru a marca faptul că un utilizator s-a conectat. Deoarece cookie-ul poate fi creat numai după ce conectarea a avut succes, este logic să stocați numele de utilizator în cookie. Un utilizator este apoi autentificat și autorizat pe baza existenței și conținutului cookie-ului. Dacă oamenii nu ar fi rău intenționați, nimic nu ar putea merge prost. Sincer să fiu, nici ei nu trebuie să fie curioși.
Dacă un utilizator curios a găsit un cookie pe computerul său, ar putea vedea ceva de genul acesta:
{"username": "joe.doe", "expires": "2018-06-01 10:28:16"}
Un dicționar Python perfect valid serializat la JSON, nimic special în el. Utilizatorul mereu curios ar putea schimba data de expirare pentru a împiedica aplicația să forțeze deconectarea. Un utilizator și mai curios ar putea încerca să modifice numele de utilizator în "jane.doe"
. Dacă acest nume de utilizator ar exista, ar deschide o lume cu totul nouă pentru utilizatorul nebănuit care are acum acces la date private.
Un exemplu simplu de serializare a datelor în JSON și de păstrare a totul transparent este departe de cel mai rău lucru care vi se poate întâmpla. Dacă un atacator reușește să modifice unele date serializate, ar putea fi capabil să le modifice într-un mod care forțează sistemul să execute cod arbitrar.
Să presupunem că construiești un API REST care le permite oamenilor să-și scrie propriile modele de învățare automată în Python și să le încarce în serviciul tău. Serviciul va evalua modelele încărcate și le va instrui folosind seturile dvs. de date. Acest lucru permite oamenilor să utilizeze resursele dvs. de calcul și o cantitate mare de seturi de date disponibile pentru construirea rapidă și ușoară a modelelor.
Serviciul nu stochează codul în format text simplu. Utilizatorii își decapă codul, îl criptează folosind cheia lor privată și îl trimit la API pentru instruire. Atunci când serviciul trebuie să ruleze un model, decriptează codul, îl decuplează și îl rulează. Partea dificilă este că protocolul murături este nesigur. Codul poate fi construit într-un mod care să permită executarea unui cod rău intenționat arbitrar în timpul deserializării.
Protocolul pickle al lui Python permite claselor să definească o metodă __reduce__
, care returnează informații despre cum să deserializeze un obiect personalizat. Una dintre valorile de returnare acceptate este un tuplu de două argumente: un apelabil și un tuplu de argumente care trebuie transmis celui apelabil. Ținând cont de faptul că sistemul dvs. de instruire a modelului ML își propune să ofere flexibilitate maximă a structurii codului, este posibil să scrieți următorul cod:
class Algo(object): def run(self): pass def __reduce__(self): import itertools return (list, (itertools.count(1), ))
Odată ce obiectul trebuie deserializat (deserializat), o list
de funcții este apelată cu un singur argument. list
de funcții este un constructor de listă în Python, iar funcția itertools.count
produce un iterator infinit de valori, începând cu parametrul transmis. Transformarea unui iterator infinit într-o listă finită poate avea consecințe dezastruoase asupra performanței și stabilității sistemului dumneavoastră.
Singurul remediu real pentru acest tip de vulnerabilitate este alegerea de a nu deserializa datele care provin din surse externe. În cazul în care acest lucru nu este posibil, se recomandă utilizarea unei sume de control sau a unei semnături digitale pentru a preveni deserializarea datelor care au fost potențial modificate de un utilizator rău intenționat. De asemenea, încercați să configurați un mediu sandbox decuplat de sistemul dvs. principal pentru a limita efectele problemelor care ar putea apărea.
Când utilizați biblioteci externe pentru deserializarea datelor, de exemplu din XML sau JSON, încercați să alegeți cele care vă permit să efectuați verificări ale tipului de obiect înainte de a fi executată o procedură de deserializare reală. Acest lucru ar putea prinde tipuri de obiecte neașteptate al căror singur scop este de a vă deteriora sistemul.
Ca și în cazul tuturor celorlalte acțiuni pe care le efectuează aplicația dvs., impuneți înregistrarea și monitorizarea extinse. Deserializările care se întâmplă des sau eșec mai mult decât în mod normal sunt semnale că ceva rău se întâmplă. Descoperiți problemele devreme.
Înregistrare și monitorizare insuficiente
Cât timp petreci pentru a te asigura că înregistrezi toate avertismentele și erorile care apar în aplicația ta? Stocați doar erorile care apar în cod sau înregistrați și erorile de validare? Ce se întâmplă atunci când regulile de afaceri ale domeniului dvs. nu sunt îndeplinite? Eșecul de a persista toate activitățile eronate și suspecte din aplicația dvs. reprezintă un compromis de securitate și de date.
Imaginează-ți următorul scenariu. Aplicația dvs. conține o pagină de conectare, așa cum o fac majoritatea. Formularul are două câmpuri, unul pentru introducerea unui e-mail și celălalt pentru o parolă. Dacă un utilizator încearcă să se conecteze și furnizează o parolă incorectă, poate încerca din nou. Din păcate, numărul de încercări incorecte nu este limitat, astfel încât pagina de conectare nu va fi blocată după N încercări nereușite. Un atacator poate folosi această oportunitate și, având un e-mail corect, continuă să introducă parole dintr-un tabel curcubeu până când o combinație reușește în sfârșit. Cu condiția ca aplicația dvs. să fie suficient de sigură și să folosiți hash parolele înainte de a le introduce într-o bază de date, acest atac special nu va funcționa. Cu toate acestea, aveți un mecanism pentru identificarea intruziunilor?
Doar pentru că această singură încercare nu a reușit să vă deschidă pagina de conectare, nu înseamnă că o altă încercare nu o va face. Pagina de conectare nu este probabil singura ușă în spate potențială pe care o aveți. Dacă nu pentru altceva, cineva ar putea încerca să folosească controlul accesului întrerupt împotriva ta. Chiar și aplicațiile perfect concepute ar trebui să știe că cineva încearcă să le atace, chiar dacă s-ar putea să nu fie posibil. Întotdeauna este, totuși.
Pentru a face tot posibilul pentru a vă proteja împotriva unor astfel de atacuri, faceți următorii pași:
- Înregistrați toate eșecurile și avertismentele care apar în aplicație, fie că sunt excepții introduse în cod sau erori de control al accesului, validare și manipulare a datelor. Toate informațiile stocate trebuie să fie replicate și păstrate suficient de mult timp astfel încât să fie posibilă inspecția și analiza retrospectivă.
- Determinarea formatului și a stratului de persistență este importantă. A avea un fișier uriaș cu format de text arbitrar este ușor de realizat; procesarea lui mai târziu nu este. Alegeți o opțiune de stocare care facilitează stocarea și citirea datelor și un format care permite (de)serializarea ușoară și rapidă. Stocarea JSON într-o bază de date care permite accesul rapid ușurează utilizarea. Păstrați baza de date mică făcându-i copii de rezervă în mod regulat.
- Dacă aveți de-a face cu date importante și valoroase, păstrați o serie de acțiuni care pot fi urmate pentru a audita starea finală. Implementați un mecanism pentru prevenirea falsificării datelor.
- Puneți sistemele de fundal să analizeze jurnalele și să vă alerteze dacă apare ceva. Verificările – care sunt la fel de simple ca testarea dacă un utilizator încearcă în mod repetat să acceseze o parte protejată a aplicației – ajută. Totuși, nu supraîncărcați sistemul cu verificări false. Sistemele de monitorizare trebuie să fie rulate ca servicii separate și nu trebuie să afecteze performanța sistemului principal.
Când rezolvați problema, aveți grijă deosebită să nu scurgeți jurnalele de erori către utilizatorii externi. Nerespectarea acestui lucru vă face susceptibil la expunerea la informații sensibile. Înregistrarea și monitorizarea ar trebui să vă ajute în rezolvarea problemelor, nu atacatorii în a-și face treaba mai eficient.
Pasii urmatori
Este important să fii conștient de potențialele amenințări și vulnerabilități din aplicațiile web. Este și mai important să începeți să le identificați în aplicațiile dvs. și să aplicați patch-urile pentru a le elimina.
Atenția acordată securității aplicațiilor este o parte importantă a tuturor etapelor proiectului de dezvoltare software. Arhitecții de software, dezvoltatorii și testerii trebuie să încorporeze proceduri de testare a software-ului în fluxurile lor de lucru. Este benefic să utilizați liste de verificare de securitate și teste automate în pașii corespunzători ai procesului de dezvoltare a software-ului pentru a reduce riscul de securitate.
Indiferent dacă analizați o aplicație existentă sau dezvoltați una nouă, ar trebui să vă uitați la Proiectul standard de verificare a securității aplicațiilor OWASP (ASVS). Scopul proiectului este de a dezvolta un standard pentru verificarea securității aplicațiilor. Standardul enumeră teste și cerințe pentru dezvoltarea aplicațiilor web securizate. Testelor li se atribuie niveluri de la unu la trei, unde unu înseamnă cel mai mic pericol și trei înseamnă cea mai mare amenințare potențială. Clasificarea permite managerilor de aplicații să decidă care dintre amenințări sunt mai probabile și mai importante. Nu este necesar să includeți fiecare test în cadrul fiecărei aplicații.
Atât proiectele de aplicații web noi, cât și cele existente, în special cele care urmează principiile Agile, beneficiază de planificarea structurată a eforturilor de securizare a aplicațiilor lor. Planificarea testelor OWASP ASVS este mai ușoară dacă decideți să utilizați OWASP Security Knowledge Framework. Este o aplicație pentru gestionarea sprinturilor orientate spre testarea securității, care vine cu un set de exemple despre cum să rezolvi problemele obișnuite de securitate și liste de verificare ușor de urmărit bazate pe OWASP ASVS.
Dacă tocmai ați început să explorați securitatea aplicațiilor web și aveți nevoie de un loc de joacă sandbox sigur, utilizați o implementare a aplicației web de la OWASP—WebGoat. Este o implementare intenționată nesigură a unei aplicații web. Aplicația vă ghidează prin lecții, fiecare lecție fiind concentrată pe o amenințare de securitate.
În timpul dezvoltării aplicației, asigurați-vă că:
- Identificați și prioritizați amenințările. Definiți ce amenințări pot apărea în mod realist și pot reprezenta un risc pentru aplicația dvs. Prioritizează amenințările și decide care merită cel mai mult efort de dezvoltare și testare. Nu prea are rost să depuneți mult efort în rezolvarea înregistrării și monitorizării insuficiente dacă serviți un blog static.
- Evaluați arhitectura și designul aplicației dvs. Unele vulnerabilități sunt foarte greu de rezolvat în fazele ulterioare ale dezvoltării aplicației. De exemplu, dacă intenționați să executați cod de la terți și nu aveți intenționați să utilizați un mediu sandbox, va fi foarte dificil să vă apărați împotriva atacurilor de deserializare și injecție nesigure.
- Actualizați procesul de dezvoltare software. Testarea împotriva amenințărilor aplicațiilor web trebuie, pe cât posibil, să fie un proces automat. Este benefic să vă măriți fluxurile de lucru CI/CD cu teste automate care încearcă să găsească găuri de securitate. Puteți chiar să utilizați sistemul de testare unitar existent pentru a dezvolta teste de securitate și a le rula periodic.
- Învață și îmbunătăți. Lista problemelor și vulnerabilităților nu este statică și cu siguranță nu se limitează la zece sau cincisprezece amenințări. Noile funcționalități și idei deschid porțile pentru noi tipuri de atacuri. Este important să citiți despre tendințele actuale din lumea securității aplicațiilor web pentru a rămâne la curent. Aplicați ceea ce învățați; altfel, iti pierzi timpul.
Concluzie
Chiar dacă, așa cum sugerează și numele, Proiectul OWASP Top Ten listează doar zece vulnerabilități de securitate, există mii de posibile capcane și uși din spate care amenință aplicațiile și, cel mai important, utilizatorii și datele lor. Asigurați-vă că fiți atent și reîmprospătați-vă constant cunoștințele, deoarece schimbările și îmbunătățirile tehnologiilor au atât avantaje, cât și dezavantaje.
A, și, nu uita, lumea nu este alb-negru. Vulnerabilitățile de securitate nu vin singure; sunt adesea împletite. A fi expus la unul înseamnă adesea că o grămadă de alții sunt la colț, așteaptă să-și ridice capetele urâte și, uneori, chiar dacă nu este vina ta, în calitate de dezvoltator de securitate a sistemului, încă ești menit să corectezi lacune pentru a reduce. criminalitatea cibernetică. Pentru un exemplu, consultați Numerele de card de credit piratate sunt încă, încă pot fi Google .