Decenijama je statičko testiranje sigurnosti aplikacija (SAST) bilo jedan od najefikasnijih načina na koji sigurnosni timovi skaliraju pregled koda.
Ali kada smo gradili Codex Security, donijeli smo svjesnu dizajnersku odluku: nismo počeli uvoziti izvještaj statičke analize niti tražiti od agenta da ga pregleda. Sistem smo osmislili da započne sa samim repozitorijem—njegovom arhitekturom, granicama povjerenja i predviđenim ponašanjem—i da provjeri ono što pronađe prije nego što zatraži od čovjeka da na to utroši vrijeme.
Razlog je jednostavan: najteže ranjivosti obično nisu problemi protoka podataka. Do toga dolazi kada se čini da kod provodi sigurnosnu provjeru, ali ta provjera zapravo ne garantuje svojstvo na koje se sistem oslanja. Drugim riječima, izazov nije samo praćenje kako se podaci kreću kroz program—već i utvrđivanje da li odbrane u kodu zaista funkcionišu.
SAST se često predstavlja kao čisti tok: identificirati izvor nepouzdanog unosa, pratiti podatke kroz program i označiti slučajeve u kojima ti podaci dospiju do osjetljivog ponora bez sanitizacije. To je elegantan model, i pokriva mnogo stvarnih grešaka.
U praksi, SAST mora praviti aproksimacije kako bi ostao izvodiv u velikim razmjerama—posebno u realnim bazama koda s indirekcijom, dinamičkim dispatchom, callbackovima, refleksijom i kontrolnim tokom koji je snažno oslonjen na okvire. Te aproksimacije nisu kritika SAST-a; one su realnost pokušaja da se rasuđuje o kodu bez njegovog izvršavanja.
To, samo po sebi, nije razlog zašto Codex Security ne počinje sa SAST izvještajem.
Glavni problem je šta se dešava nakon što uspješno pratite izvor do ponora.
Čak i kada statička analiza tačno prati unos kroz više funkcija i slojeva, još uvijek mora odgovoriti na pitanje koje zapravo odlučuje postoji li ranjivost:
Uzmite uobičajen obrazac: kod poziva nešto poput sanitize_html() prije prikazivanja nepouzdanog sadržaja. Statički analizator može vidjeti da je sanitizer pokrenut. Ono što obično ne može utvrditi jeste da li je taj sanitizer zaista dovoljan za specifični kontekst prikazivanja, šablonski mehanizam, ponašanje kodiranja i uključene nizvodne transformacije.
Tu stvari postaju nezgodne. Problem nije samo u tome da li podaci dospiju do odredišta. Radi se o tome da li provjere u kodu zaista ograničavaju vrijednost na način na koji sistem pretpostavlja da to čine.
Drugim riječima: postoji velika razlika između „kod poziva sanitizer“ i „sistem je siguran“.
Evo obrasca koji se stalno pojavljuje u stvarnim sistemima.
Web aplikacija prima JSON payload, izdvaja redirect_url, provjerava ga prema regex listi dopuštenih URL-ova, dekodira ga i prosljeđuje rezultat handleru za preusmjeravanje.
Klasični izvještaj od izvora do ponora može opisati tok:
nepouzdan ulaz → regex provjera → dekodiranje URL-a → preusmjeravanje
Ali pravo pitanje nije da li provjera uopšte postoji. Pitanje je da li ta provjera još uvijek ograničava vrijednost nakon transformacija koje slijede.
Ako se regex pokreće prije dekodiranja, da li on zaista ograničava dekodirani URL onako kako ga tumači rukovalac preusmjeravanja?
Odgovoriti na to znači vršiti rezonovanje o cijelom lancu transformacije: šta regex dopušta, kako se ponašaju dekodiranje i normalizacija, kako URL parsiranje tretira rubne slučajeve i kako logika preusmjeravanja razrješava sheme i autoritete.
Mnoge ranjivosti koje su važne u praksi izgledaju ovako: greške u redoslijedu operacija, djelimična normalizacija, dvosmislenosti u parsiranju i neusklađenosti između validacije i interpretacije. Tok podataka je vidljiv. Slabost je u tome kako se ograničenja propagiraju—ili se ne propagiraju—kroz lanac transformacija.
Ovo nije samo teorijski obrazac. U CVE-2024-29041(otvara se u novom prozoru), Express je bio pogođen problemom otvorenog preusmjeravanja gdje su nepravilno oblikovani URL-ovi mogli zaobići uobičajene implementacije liste dozvoljenih zbog načina kodiranja i interpretacije ciljeva preusmjeravanja. Tok podataka je bio jednostavan. Teže pitanje — i ono koje je odredilo da li je greška postojala — bilo je da li je validacija i dalje važila nakon lanca transformacija.
Codex Security je izgrađen s jednostavnim ciljem: smanjiti trijažu isticanjem problema s jačim dokazima. U proizvodu to znači korištenje konteksta specifičnog za repozitorij (uključujući model prijetnji) i provjeru visokosignalnih problema u izoliranom okruženju prije nego što se prikažu.
Kada Codex Security naiđe na granicu koja izgleda kao „validacija“ ili „sanitizacija“, ne tretira to kao potvrdni okvir. Pokušava razumjeti šta kod pokušava garantovati—i onda pokušava opovrgnuti tu garanciju.
U praksi to obično izgleda kao mješavina:
- Čitanje relevantne putanje koda uz puni kontekst repozitorija, na način istraživača sigurnosti, i traženje neslaganja između namjere i implementacije. Ovo uključuje komentare, ali model ne vjeruje nužno komentarima, pa dodavanje //Halvar kaže: ovo nije greška iznad vašeg koda ga ne zbunjuje, ako zaista postoji greška.
- Svođenje problema na najmanji dio koji se može testirati (na primjer, transformacijski pipeline oko jednog ulaza) kako biste o tome mogli razmišljati bez da vam ostatak sistema stoji na putu. U tom smislu, Codex Security izdvaja sićušne isječke koda, a zatim za njih piše mikro-fuzzere.
- Rezonovanje o ograničenjima kroz transformacije, umjesto tretiranja svake provjere nezavisno. Gdje je to prikladno, ovo može uključivati formalizaciju kao pitanje zadovoljivosti. Drugim riječima, dajemo modelu pristup Python okruženju sa z3-solverom i on je dobar u njegovom korištenju kada je to potrebno, baš kao što bi i čovjek morao biti kada odgovara na posebno složen problem ograničenja ulaza. Ovo je posebno korisno za istraživanje prelijevanja cijelih brojeva ili sličnih grešaka na nestandardnim arhitekturama.
- Izvršavanje hipoteza u okruženju za validaciju sa sandboxom kada je to moguće, kako bi se razlikovalo „ovo bi mogao biti problem“ od „ovo jeste problem“. Nema boljeg dokaza od potpunog PoC-a od početka do kraja sa kodom kompajliranim u debug režimu.
Ovo je ključni pomak: umjesto da se zaustavi na „provjera postoji“, sistem gura prema „invarijanta važi (ili ne važi), i evo dokaza“. A model bira najbolji alat za taj posao.
Razumna reakcija je: zašto ne uraditi oboje? Počnite sa SAST izvještajem, zatim koristite agenta za dublje razmišljanje.
Postoje slučajevi u kojima su unaprijed izračunati nalazi korisni—posebno za uske, poznate klase grešaka. Ali za agenta dizajniranog da otkriva i potvrđuje ranjivosti u kontekstu, započinjanje od SAST izvještaja stvara tri predvidiva načina kvara.
Prvo, to može potaknuti preuranjeno sužavanje. Lista nalaza je mapa mjesta gdje je alat već pregledao. Ako to tretirate kao početnu tačku, možete usmjeriti sistem da ulaže neproporcionalan napor u iste regije, koristi iste apstrakcije i propušta klase problema koje se ne uklapaju u svjetonazor alata.
Drugo, može uvesti implicitna prosuđivanja koja je teško razmrsiti. Mnogi SAST nalazi kodiraju pretpostavke o sanitizaciji, validaciji ili granicama povjerenja. Ako su te pretpostavke pogrešne—ili samo nepotpune—unošenje njih u petlju rezonovanja može pomjeriti agenta sa „istraži” na „potvrdi ili odbaci,” što nije ono što želimo da agent uradi.
Treće, to može otežati evaluaciju sistema za rezonovanje. Ako pipeline počinje sa SAST izlazom, postaje teško razdvojiti ono što je agent otkrio kroz vlastitu analizu od onoga što je naslijedio od drugog alata. To razdvajanje je važno ako želite tačno mjeriti sposobnosti sistema, što je potrebno kako bi se sistem poboljšavao tokom vremena.
Zato smo izgradili Codex Security da počne tamo gdje počinju sigurnosna istraživanja: od koda i namjere sistema, uz validaciju koja se koristi da podigne ljestvicu povjerenja prije nego što prekinemo osobu.
SAST alati mogu biti odlični u onome za šta su dizajnirani: provođenju sigurnih standarda kodiranja, hvatanju jednostavnih problema od izvora do odredišta i otkrivanju poznatih obrazaca u velikom obimu uz predvidljive kompromise. Oni mogu biti snažan dio odbrane u dubini.
Ovaj post je uži: govori o tome zašto agent koji je dizajniran da rezonuje o ponašanju i provjerava nalaze ne bi trebao započeti rad oslanjajući se na statičnu listu nalaza.
Također je vrijedno istaknuti jedno povezano ograničenje čistog razmišljanja od izvora do ponora: nije svaka ranjivost problem toka podataka. Mnogi stvarni kvarovi su problemi stanja i invarijanti—zaobilaženja radnog toka, praznine u ovlaštenjima i greške tipa „sistem je u pogrešnom stanju“. Za ove vrste grešaka, kontaminirana vrijednost ne dospijeva do nijednog „opasnog ponora“. Rizik leži u onome što program pretpostavlja da će uvijek biti tačno.
Očekujemo da će se ekosistem sigurnosnih alata nastaviti poboljšavati: statička analiza, fuzzing, zaštite tokom izvršavanja i tokovi rada s agentima će svi imati svoje uloge.
Ono što želimo da Codex Security najbolje radi je upravo ono što najviše košta sigurnosne timove: pretvaranje „ovo izgleda sumnjivo“ u „ovo je stvarno, evo gdje je problem i evo rješenja koje odgovara namjeri sistema“.
Ako želite saznati više o tome kako Codex Security skenira repozitorije, validira nalaze i predlaže ispravke, pogledajte našu dokumentaciju(otvara se u novom prozoru).


