Cum se utilizează corect analiza statică
Acualmente se vorbește din ce în ce mai mult despre analiza statică pentru căutarea vulnerabilităților ca etapă necesară a procesului de dezvoltare. Cu toate acestea, mulți vorbesc și despre problemele analizei statice. Dacă ați încercat vreun instrument specializat, puteți fi înspăimântat de rapoarte lungi, cu recomandări confuze, dificultăți în configurarea instrumentului și falsuri pozitive. Deci este încă necesară analiza statică?
Experiența sugerează că este necesar. Și multe dintre problemele care apar atunci când vă uitați prima dată la instrument, este destul de posibil să rezolvați. Voi încerca să vă spun ce poate face utilizatorul și cum ar trebui să fie analizatorul astfel încât utilizarea sa să fie utilă și să nu se introducă „un alt instrument inutil, de care are nevoie Security Officer”.
Despre analiza statică
Deci, am vorbit deja despre limitările teoretice ale analizei statice. De exemplu, analiza statică profundă încearcă să rezolve probleme care sunt exponențiale în complexitate. Prin urmare, fiecare instrument caută un compromis între timpul necesar, resursele cheltuite, numărul de vulnerabilități găsite și numărul de falsuri pozitive.
De ce avem nevoie de analize aprofundate? Orice IDE găsește foarte repede erori, uneori chiar și legate de securitate – care sunt unele probleme exponențiale? Un exemplu clasic este SQL injection (și orice altă injecție, cum ar fi XSS, RCE și altele asemenea), care trece prin mai multe funcții (adică citirea datelor de la utilizator și executarea interogării apar în diferite funcții). Căutarea acestuia necesită o analiză interprocedurală a fluxului de date, iar aceasta este o sarcină de complexitate exponențială. De acord, fără a căuta astfel de vulnerabilități, analiza nu poate fi considerată profundă. Din același motiv, trebuie să analizați codul în întregime și nu în părți – altfel, vulnerabilitățile interprocedurale pot fi ratate.
În ultimii ani, am acumulat multă experiență în comunicarea cu clienții (potențiali) ai diferiților analizoare statice. În special, discutăm revendicările la instrumente pe baza rezultatelor primei utilizări (pilot). Majoritatea revendicărilor urmează într-un fel sau altul din limitările teoretice ale tehnologiei. În plus, este posibil ca instrumentele să nu aibă pur și simplu funcționalitatea de care utilizatorul are nevoie. Cu toate acestea, în opinia noastră, analizatorii se pot deplasa (și se îndreaptă) către utilizator în ceea ce privește rezolvarea problemelor identificate mai jos. Dar, de asemenea, trebuie să poți folosi analizoare, nivelând consecințele acelorași probleme – după cum se dovedește, acest lucru nu este atât de dificil. Hai să mergem în ordine.
Vă puteți imagina o situație de model: decideți să încercați tehnologia în acțiune sau să alegeți un analizor static – efectuați un pilot. Desigur, nu aveți încredere în cazurile de test ale furnizorului și doriți să încercați să analizați codul dvs. (în același timp puteți găsi vulnerabilități reale și să le remediați). Vi se oferă un program de instalare sau o mașină virtuală pre-configurată cu un sistem pentru o perioadă scurtă de timp.
Începutul analizei
Mai întâi trebuie să lansați analiza. Accesați interfață și totul pare clar: încărcați arhiva cu codul sursă și faceți clic pe „analiză”. Dar nu: primiți mai multe formulare cu câmpuri diferite care trebuie completate cumva. Este necesar să indicați limbaje de programare, unele setări ale analizorului, selectați pachete de vulnerabilitate (de unde știți ce este inclus în ele?) Ș.a. Treci acest test și începe analiza. Ah, nu – o eroare de scanare. „Formatul nu corespunde cerințelor”, „Este necesar un set de coduri pentru această limbă”, „Fișierele pentru scanare nu au fost găsite” … Dacă nu ați scris acest cod singur, va trebui să vă adresați dezvoltatorilor pentru ajutor.
Dezvoltatorul trimite codul sursă pentru testare.
O atenție deosebită se acordă cerințelor pentru construirea codului. Majoritatea analizatorilor pentru mai multe limbi necesită colectarea codului în timpul analizei (limbaje JVM – Java, Scala, Kotlin și altele asemenea, C / C ++, Objective-C, C #). Înțelegeți cât de dureros este: reproducerea mediului unui proiect mare de asamblare pe o mașină nouă. Pe de altă parte, aceste cerințe sunt justificate, ele provin din tehnologia de analiză și specificul acestor limbi.
Cum rezolvă analizatorii aceste probleme? În primul rând, acestea fac ca analiza să fie executată cât mai automat. În mod ideal, este suficient să descărcați un fișier de orice format, iar analizatorul însuși trebuie să înțeleagă ce limbi există, cum să încercați să construiți și cum să setați restul setărilor implicite, astfel încât rezultatele să fie cât mai complete. Este clar că este imposibil să prevedeți totul – cu toate acestea, puteți încerca să rezolvați majoritatea cazurilor.
Cerințele de asamblare trebuie făcute cât mai ușoare. De exemplu, pentru limbajele JVM, nu trebuie să solicitați asamblare în timpul analizei – cereți doar să încărcați artefacte, adică codul asamblat împreună cu sursele (care este mult mai simplu). Pentru Xcode, în cazul Obiectiv-C, ansamblul poate fi automatizat pentru majoritatea cazurilor. Dacă nu a fost posibilă colectarea codului, analizatorul poate încerca să efectueze o analiză parțială. Rezultatele sale nu vor fi atât de complete, dar este mai bine decât niciun rezultat. De asemenea, este convenabil dacă modulul de analiză poate fi pus pe aparat către dezvoltator, unde ansamblul codului este deja configurat, în timp ce arhitectura ar trebui să permită transferul celorlalte module și a părții de interfață către o altă mașină.
În cele din urmă, analizatorul ar trebui să prezinte cele mai soft cerințe de format și să se ocupe de fișierele de intrare în sine. Arhivă cu cod sursă, arhive cuibărită, arhivă dintr-un depozit, legătură către un depozit, arhivă dintr-un produs, fișier executabil dintr-un produs – este bine dacă analizatorul acceptă toate acestea.
Totuși, nu uitați că analizatorul nu are inteligență artificială și nu poate prevedea totul. Prin urmare, dacă apar erori, ar trebui să vă familiarizați cu manualul – există multe lucruri utile în pregătirea codului pentru analiză. Ei bine, toată această lucrare de lansare a unei scanări în timpul implementării analizorului se face o singură dată pentru fiecare bază de cod. Cel mai adesea, analizorul este în general integrat în ciclul CI, adică nu vor fi probleme cu ansamblul.
Analiza statică – procesul
Bine, scanarea a început. Trece o oră – fără rezultate. Bara de progres atârnă undeva la mijloc, nu este clar cu ce procent și ce prognoză este finalizată. A doua oră trece – progresul s-a mutat 99 la sută și a fost atârnat acolo timp de o jumătate de oră. Trece o a treia oră – iar analizatorul se prăbușește, raportând o lipsă de memorie RAM. Sau atârnă încă o oră și se termină. Te-ai putea aștepta ca analiza să treacă la aceeași viteză ca și stilul tău de control, iar așteptările se vor abate foarte mult de realitate.
Da, un bun analizator static poate consuma o mulțime de resurse, am subliniat unul dintre motivele de mai sus: găsirea vulnerabilităților complexe este o sarcină exponențial dificilă. Așadar, cu cât există mai multe resurse și cu atât mai mult timp, cu atât vor fi rezultate mai bune (cu un motor bun, desigur). Este cu adevărat dificil să prezicem atât timpul de analiză, cât și resursele necesare – timpul de funcționare al algoritmilor de analiză statică depinde puternic de constructele limbajului, de complexitatea codului, de profunzimea apelurilor – de caracteristici dificil de calculat în avans.
Problema resurselor este un rău necesar. Trebuie să luați în considerare alocarea resurselor necesare, să așteptați cu răbdare finalizarea scanării și, de asemenea, să înțelegeți că nimeni nu poate prezice cu exactitate resursele necesare pentru analizor, chiar și cu o bază de cod dată, și trebuie să fiți pregătiți să modificați acești parametri. Mai mult, parametrii necesari se pot schimba chiar și fără actualizarea bazei de cod – datorită actualizării analizatorului.
Cu toate acestea, analizorul poate ajuta puțin cu această problemă. Este capabil să separe partea de consum intensiv (motoare) și interfața în diferite mașini. Acest lucru vă va permite să nu încărcați mașini cu programe inutile care să încetinească funcționarea acestora, în timp ce va fi posibilă utilizarea interfeței sistemului pentru orice volum de lucru pe scanări (de exemplu, pentru a vizualiza și edita rezultatele). Acest lucru va facilita, de asemenea, scalarea fără a reinstala întregul sistem (ridicăm analizorul pe o nouă mașină virtuală, specificăm IP-ul mașinii principale – și voila).
În plus, analizorul vă poate permite să selectați profunzimea analizei, să dezactivați verificările grele, să utilizați analiza incrementală (în care nu este verificat tot codul, ci doar modificat). Aceste lucruri trebuie utilizate foarte atent, deoarece pot afecta foarte mult rezultatele scanării. Dacă utilizați o astfel de funcționalitate, este recomandat să efectuați o analiză completă la anumite intervale de timp.
Rezultatele analizei
Să trecem la rezultatele scanării (multă vreme am fost la ele). Aștepți numărul de vulnerabilități din fereastra analizatorului cu trepidare și ești foarte surprins să-l vezi. 156 Critical, 1260 Normal și 3210 Low. Accesați pagina cu rezultatele și vă pierdeți în numărul de probleme găsite. Descărcați un raport pdf și vedeți câteva mii de pagini de text. Ghiciți ce va spune dezvoltatorul de aplicație atunci când va vedea un astfel de rezultat?
Security officer transmite raportul de vulnerabilitate dezvoltatorului,
Să încercăm să analizăm rezultatele, să-i oferim o șansă. După ce ai studiat îndeaproape câteva zeci de evenimente, începi să înțelegi de ce există atât de multe vulnerabilități. Mai multe vulnerabilități arată într-adevăr grave, înțelegeți că acestea trebuie rezolvate. Totuși, imediat veți găsi aproximativ o duzină de false. Și, de asemenea, un număr imens de vulnerabilități în codul bibliotecilor. Nu veți corecta bibliotecile! Și atunci înțelegeți cât timp veți petrece analiza rezultatelor. Și această procedură trebuie repetată în fiecare zi, săptămână, bine, sau cel puțin la fiecare versiune. (De fapt nu).
Pentru început, falsele pozitive pot fi înțelese în moduri foarte diferite. Cineva nu va considera false vulnerabilități critice false care pot fi exploatate chiar acum. Cineva va considera false erori explicite false ale analizatorului. Mult depinde de ceea ce doriți de la instrument. Vă recomandăm să luați în considerare aproape toate aparițiile, deoarece chiar și o vulnerabilitate la nivel scăzut care nu poate fi exploatată chiar acum se poate transforma într-o problemă serioasă mâine, de exemplu, din cauza modificărilor codului și a condițiilor externe.
Ok, trebuie să te uiți la toate intrările, dar aceasta este încă o cantitate imensă de muncă. Și aici analizatorii pot ajuta foarte bine. Cea mai importantă funcție a analizorului este abilitatea de a urmări vulnerabilitățile între scanările unui proiect, în timp ce urmărirea este rezistentă la mici modificări care sunt standard pentru dezvoltarea codului. Acest lucru înlătură problema că trebuie repetată o analiză lungă a vulnerabilităților: prima dată petreci mai mult timp, eliminând falsele pozitive și schimbând criticitatea aparițiilor, dar va trebui doar să te uiți la vulnerabilități noi, care vor fi de câteva ori mai mici.
Bun, dar este necesar să revizuiți toate vulnerabilitățile pentru prima dată? Vă recomandăm să faceți acest lucru, dar, în general, acest lucru nu este necesar. În primul rând, analizatorii vă permit să filtrați rezultatele după directoare și fișiere: de exemplu, atunci când începeți o scanare, puteți exclude imediat din analiză orice componente, biblioteci, cod de testare. Acest lucru va afecta viteza de analiză. În al doilea rând, analizatorii vă permit să filtrați rezultatele în funcție de vulnerabilități, adică atunci când începeți scanarea, puteți limita setul de vulnerabilități. În sfârșit, pe lângă critică, analizatorul poate produce ceva precum probabilitatea unei false vulnerabilități (adică încrederea acestuia în această vulnerabilitate). Folosind această măsurătoare, puteți filtra rezultatele.
Ar trebui să menționăm și analiza compoziției software-ului tehnologic (acum începe să fie susținută de un număr tot mai mare de instrumente la diferite niveluri). Tehnologia vă permite să detectați utilizarea bibliotecilor din codul dvs., să determinați numele și versiunile, să prezentați vulnerabilitățile cunoscute, precum și licențele. Această tehnologie poate separa codul bibliotecii de cel propriu, care poate filtra și rezultatele.
Se dovedește că este posibil să se rezolve problema rezultatelor analizei abundente, iar acest lucru nu este foarte dificil. Și deși prima vizualizare a rezultatelor poate dura cu adevărat timp, atunci când o scanați, aceasta va fi cheltuită din ce în ce mai puțin. Cu toate acestea, observ din nou că ar trebui să fii atent la orice filtrare a rezultatelor – poți sări peste vulnerabilitate. Chiar dacă biblioteca este cunoscută, aceasta nu înseamnă că nu există vulnerabilitate în ea. Dacă acum această vulnerabilitate este detectată slab (adică instrumentul prezintă o mulțime de falsuri pozitive pentru această vulnerabilitate) și o dezactivezi, la actualizarea analizorului, poți sări peste vulnerabilitatea reală.
Să verificăm analizatorul.
Ne-am clarificat cu raportul mare și cu fals pozitiv. Dar doriți să mergeți mai departe – pentru a vă asigura că analizatorul găsește acele vulnerabilități despre care știți sigur (ați putea să le puneți în mod deliberat sau să găsiți un alt instrument).
Pentru început, este important să înțelegem că analizatorul nu a putut găsi vulnerabilitatea din diferite motive. Cel mai simplu este că scanarea a fost configurată incorect (trebuie să fiți atenți la mesajele de eroare). Dar din punct de vedere al tehnologiei de analiză, motivele pot fi diferite. Un analizator static constă din două componente importante: un motor (conține toată complexitatea algoritmică și matematica) și o bază de date cu reguli de căutare a vulnerabilității. O situație este aceea când motorul vă permite să găsiți o vulnerabilitate a acestei clase, dar nu există o vulnerabilitate în baza de reguli. În acest caz, adăugarea unei reguli nu este de obicei dificilă. O situație complet diferită, dacă motorul, în principiu, nu acceptă astfel de vulnerabilități, aici revizuirea poate fi foarte semnificativă. Am dat un exemplu la începutul articolului: injecția SQL nu poate fi găsită niciodată fără algoritmi de analiză a fluxului de date.
Un analizator static ar trebui să implementeze un set de algoritmi în motor care acoperă clasele disponibile de vulnerabilități pentru un anumit limbaj de programare (analiza fluxului de control, analiza fluxului de date, analiza de intervale etc.). Un punct important este capacitatea de a adăuga propriile reguli de căutare a vulnerabilității la instrument – acest lucru va elimina primul motiv pentru care lipsește o vulnerabilitate.
Astfel, dacă nu ați găsit o vulnerabilitate existentă în rezultatele scanării, mai întâi trebuie să aflați motivul săririi – de obicei un furnizor vă poate ajuta. Dacă motivul se află în baza regulilor sau în configurația de scanare, atunci situația poate fi destul de ușor eliminată. Cel mai important este să evaluați profunzimea analizei, adică ceea ce vă permite, în principiu, să căutați motorul.
Competențe
După citirea articolului până în acest moment, putem presupune că pentru a lucra cu instrumentul este necesară o expertiză profundă a dezvoltatorului, deoarece trebuie să înțelegeți care sunt răspunsurile false și care sunt adevărate. În opinia mea, totul depinde de cât de prietenos se comportă instrumentul. Dacă oferă funcționalități convenabile și de înțeles, descrieri inteligibile ale vulnerabilităților, cu exemple, link-uri și recomandări în diferite limbi, dacă instrumentul prezintă urme pentru vulnerabilități legate de analiza fluxului de date, nu va trebui să aveți o expertiză profundă a dezvoltatorului cu o înțelegere a tuturor subtilităților limbajului de programare și cadre. Cu toate acestea, trebuie să existe un fond minim de dezvoltare pentru a putea citi codul.
Integrare analiza statică în procesul de dezvoltare
La sfârșitul articolului, vom atinge pe scurt una dintre cele mai importante probleme ale utilizării instrumentului și o vom analiza în detaliu în articolele următoare. Să presupunem că decideți să utilizați un analizor static. Cu toate acestea, aveți un proces de dezvoltare stabilit, atât tehnologic, cât și organizațional și nu doriți să-l schimbați (da, nu o va face nimeni).
Instrumentul trebuie să aibă o interfață completă non-grafică (de exemplu, API CLI sau REST), cu care puteți integra analizorul în oricare dintre procesele dvs. Este bine dacă analizorul are integrări gata făcute cu diverse componente: plug-in-uri pentru IDE sau sisteme de construire, integrări cu sisteme de control de versiuni, plug-inuri pentru servere CI / CD (Jenkins, TeamCity), integrare cu sisteme de management de proiect (JIRA) sau lucrează cu utilizatorii ( Directory Active).
Integrarea analizei statice în procesul de dezvoltare (așa-numitul SDLC) este cea mai eficientă metodă de utilizare a acestuia dacă procesul este bine stabilit și toți participanții sunt de acord și știu de ce este necesar acest lucru. Analiza constantă a codului după modificări sau actualizări ale analizorului vă va permite să găsiți vulnerabilități cât mai devreme. Separarea rolurilor dezvoltatorilor și specialiștilor în securitatea informațiilor, o indicație clară a cerințelor de securitate a informațiilor și integrarea soft în procesul curent (de exemplu, la început – natura consultativă a sistemului) vă va permite să utilizați instrumentul fără durere și în mod util. Cu toate acestea, nimeni nu a anulat utilizarea manuală a instrumentului, dacă modelul dvs. de dezvoltare nu implică un proces similar.
Analiza Statică – Rezumat
Articolul conține recomandări de bază pentru începerea utilizării unui analizor static. Un analizator bun funcționează într-o ordine de mărime mai bună decât orice verificator ușor; caută probleme cu o complexitate fundamental diferită. Prin urmare, este necesar să luăm în considerare caracteristicile analizei statice ca tehnologie, dar, în același timp, alegeți un instrument specific, astfel încât funcționalitatea sa să netezească maxim toate aceste caracteristici.