Pereiti prie pagrindinio turinio
OpenAI

2026 m. kovo 16 d.

ProduktasSaugumas

Kodėl „Codex Security“ neįtraukia SAST ataskaitos

Dešimtmečius statinis taikomųjų programų saugumo testavimas (angl. Static Application Security Testing, SAST) buvo vienas efektyviausių būdų saugumo komandoms išplėsti kodo peržiūros mastą.

Tačiau kurdami „Codex Security“, padarėme sąmoningą dizaino sprendimą: nepradėjome nuo statinės analizės ataskaitos importavimo ir prašymo agentui ją surūšiuoti. Sukūrėme sistemą taip, kad ji pradėtų nuo pačios saugyklos – jos architektūros, pasitikėjimo ribų ir numatyto elgesio – ir patvirtintų tai, ką randa, prieš prašydama žmogaus skirti tam laiko. 

Priežastis paprasta: sudėtingiausios pažeidžiamumo spragos paprastai nėra duomenų srauto problemos. Jos atsiranda, kai atrodo, jog kodas vykdo saugumo patikrą, tačiau toji patikra iš tikrųjų negarantuoja savybės, kuria pasikliauja sistema. Kitaip tariant, iššūkis – ne tik stebėti, kaip duomenys juda programoje, bet ir nustatyti, ar kodo apsaugos priemonės tikrai veikia.

Problema: SAST optimizuotas duomenų srautui

SAST dažnai pristatomas kaip švarus procesas: nustatyti nepatikimos įvesties šaltinį, sekti duomenis programoje ir pažymėti atvejus, kai tie duomenys pasiekia jautrų imtuvą be valymo. Tai elegantiškas modelis, apimantis daug tikrų klaidų.

Praktiškai SAST turi daryti apytikrius skaičiavimus, kad išliktų valdomas dideliu mastu – ypač realiose kodo bazėse su netiesioginėmis nuorodomis, dinaminiu išsiuntimu, atgaliniais iškvietimais, refleksija ir sistemų stipriai veikiamu valdymo srautu. Šie apytikriai skaičiavimai nėra SAST trūkumas; tai realybė bandant protauti apie kodą jo nevykdant.

Vien tai nėra priežastis, kodėl „Codex Security“ nepradeda nuo SAST ataskaitos.

Gilesnė problema yra ta, kas nutinka sėkmingai atsekus šaltinį iki duomenų gavėjo.

Kur atliekant statinę analizę susiduriama su sunkumais: apribojimai ir semantika

Net kai statinė analizė teisingai atseka įvestį per kelias funkcijas ir sluoksnius, ji vis tiek turi atsakyti į klausimą, kuris iš tikrųjų lemia, ar egzistuoja pažeidžiamumas:

Ar apsauga tikrai suveikė?

Paimkime dažną šabloną: kodas iškviečia kažką panašaus į sanitize_html() prieš atvaizduodamas nepatikimą turinį. Statinis analizatorius gali matyti, kad duomenų valymo funkcija buvo paleista. Ko jis dažniausiai negali nustatyti, tai ar ši duomenų valymo funkcija iš tikrųjų pakankama konkrečiam atvaizdavimo kontekstui, šablonų varikliui, kodavimo elgsenai ir susijusioms tolesnėms transformacijoms.

Čia ir prasideda sudėtingiausia dalis. Problema ne tik tai, ar duomenys pasiekia gavėją. Esmė ta, ar kodo patikros iš tikrųjų apriboja reikšmę taip, kaip sistema mano.

Kitaip tariant, yra didelis skirtumas tarp „kodas iškviečia valymo funkciją“ ir „sistema saugi“.

Pavyzdys: patvirtinimas prieš iškoduojant

Štai šablonas, kuris nuolat pasitaiko realiose sistemose.

Saityno programa gauna JSON naudingąją apkrovą, ištraukia redirect_url, patvirtina jį pagal leidžiamųjų sąrašo reguliarųjį reiškinį, URL iškoduoja jį ir perduoda rezultatą peradresavimo dorokliui.

Klasikinė ataskaita nuo šaltinio iki imtuvo gali apibūdinti šį srautą:

nepatikima įvestis → reguliariojo reiškinio patikra → URL iškodavimas → peradresavimas

Tačiau tikrasis klausimas nėra, ar patikra egzistuoja. Esmė ta, ar toji patikra vis dar apriboja reikšmę po tolesnių transformacijų.

Jei reguliarusis reiškinys paleidžiamas prieš iškoduojant, ar jis iš tikrųjų apriboja iškoduotą URL taip, kaip jį interpretuoja peradresavimo doroklis?

Atsakyti į šį klausimą reiškia protauti apie visą transformacijos grandinę: ką leidžia reguliarusis reiškinys, kaip veikia iškodavimas ir normalizavimas, kaip URL analizė apdoroja ribinius atvejus ir kaip peradresavimo logika išsprendžia schemas bei autoritetus.

Daugelis praktikoje svarbių pažeidžiamumo spragų atrodo būtent taip: operacijų tvarkos klaidos, dalinis normalizavimas, analizės dviprasmybės ir neatitikimai tarp patvirtinimo bei interpretavimo. Duomenų srautas matomas. Silpnybė slypi tame, kaip apribojimai plinta – arba neplinta – per transformacijos grandinę.

Tai nėra tik teorinis šablonas. Pažeidžiamume CVE-2024-29041(atsidaro naujame lange) „Express“ paveikė atvirojo peradresavimo problema: netinkamai suformuoti URL galėjo apeiti įprastus leidžiamųjų sąrašų įgyvendinimus dėl to, kaip peradresavimo taikiniai buvo užkoduojami ir vėliau interpretuojami. Duomenų srautas buvo paprastas. Sunkesnis klausimas – ir tas, kuris lėmė, ar klaida egzistuoja, – buvo tai, ar patvirtinimas vis dar galiojo po transformacijos grandinės.

Mūsų požiūris: pradėti nuo elgsenos, tada patvirtinti

„Codex Security“ sukurta siekiant paprasto tikslo: sumažinti rūšiavimą, iškeliant problemas su svaresniais įrodymais. Produkte tai reiškia, kad naudojamas konkrečios saugyklos kontekstas (įskaitant grėsmių modelį) ir stipraus signalo problemos patvirtinamos izoliuotoje aplinkoje prieš jas pateikiant. 

Kai „Codex Security“ susiduria su riba, kuri atrodo kaip „patvirtinimas“ arba „valymas“, ji nelaiko to tik formaliu patikrinimu. Ji bando suprasti, ką kodas bando garantuoti, – o tada bando tą garantiją paneigti.

Praktiškai tai dažniausiai atrodo kaip toliau nurodytų veiksmų derinys.

  • Atitinkamo kodo kelio skaitymas su visu saugyklos kontekstu taip, kaip tai darytų saugumo tyrėjas, ir ketinimo bei įgyvendinimo neatitikimų ieškojimas. Tai apima komentarus, bet modelis nebūtinai jais tiki, todėl pridėjus //Halvar says: this is not a bug (Halvaras sako: tai nėra klaida) virš kodo, jis nebus suklaidintas, jei klaida tikrai yra.
  • Problemos sumažinimas iki mažiausios testuojamos dalies (pavyzdžiui, transformacijos proceso aplink vieną įvestį), kad galėtumėte apie ją protauti be likusios sistemos trukdžių. Šia prasme „Codex Security“ išskiria mažas kodo dalis ir joms kuria izoliuotus patikrinimus (angl. „micro-fuzzers“).
  • Protavimas apie apribojimus visose transformacijose, užuot kiekvieną patikrą vertinus atskirai. Kai tinkama, tai gali apimti formalizavimą kaip įvykdomumo klausimą. Kitaip tariant, mes suteikiame modeliui prieigą prie „Python“ aplinkos su „z3-solver“, ir jis puikiai moka ja naudotis, kai reikia, kaip tai turėtų daryti žmogus, atsakinėdamas į ypač sudėtingą įvesties apribojimų problemą. Tai ypač naudinga ieškant sveikųjų skaičių perpildymo ar panašių klaidų nestandartinėse architektūrose.
  • Hipotezių vykdymas smėliadėžės tipo patvirtinimo aplinkoje, kai tai įmanoma, siekiant atskirti „tai galėtų būti problema“ nuo „tai yra problema“. Nėra geresnio įrodymo nei visapusiškas koncepcijos įrodymas (PoC) su kodu, sukompiliuotu derinimo režimu. 

Tai pagrindinis pokytis: užuot apsiribojusi tuo, kad „patikra egzistuoja“, sistema siekia nustatyti, ar invarianto sąlyga galioja (ar ne), ir pateikia tai patvirtinančius įrodymus. O modelis šiam darbui pasirenka geriausią įrankį.

Kodėl nepradedame „Codex Security“ nuo SAST ataskaitos

Pagrįsta reakcija: kodėl nepadarius abiejų? Pradėti nuo SAST ataskaitos, o tada naudoti agentą, kad šis giliau protautų.

Yra atvejų, kai iš anksto apskaičiuoti radiniai naudingi – ypač siauroms, žinomoms klaidų klasėms. Tačiau agentui, sukurtam atrasti ir patvirtinti pažeidžiamumo spragas kontekste, pradžia nuo SAST ataskaitos sukuria tris nuspėjamus nesėkmės režimus.

Pirma, tai gali per anksti susiaurinti analizę. Radinių sąrašas – tai žemėlapis, rodantis, kur įrankis jau ieškojo. Jei laikysite tai pradiniu tašku, galite nukreipti sistemą neproporcingai daug pastangų skirti toms pačioms sritims, naudoti tas pačias abstrakcijas ir praleisti problemų klases, kurios neatitinka įrankio pasaulėžiūros.

Antra, tai gali įvesti numanomus sprendimus, kuriuos sunku atšaukti. Daugelyje SAST radinių užkoduotos prielaidos apie valymą, patvirtinimą ar pasitikėjimo ribas. Jei šios prielaidos klaidingos – ar tiesiog neišsamios – jų pateikimas į protavimo ciklą gali paskatinti agentą ne tirti, o patvirtinti arba atmesti. Iš agento norime ne to.

Trečia, tai gali apsunkinti protavimo sistemos vertinimą. Jei procesas prasideda nuo SAST išvesties, pasidaro sunku atskirti, ką agentas atrado atlikdamas savo analizę, nuo to, ką jis paveldėjo iš kito įrankio. Svarbu tai atskirti, jei norite tiksliai išmatuoti sistemos galimybes, o tai būtina, kad sistema ilgainiui tobulėtų.

Todėl sukūrėme „Codex Security“ taip, kad ji pradėtų ten, kur prasideda saugumo tyrimai: nuo kodo ir sistemos ketinimo, o patvirtinimą naudotų pasitikėjimo lygiui padidinti prieš įtraukiant žmogų.

SAST įrankiai vis dar labai svarbūs

SAST įrankiai gali puikiai atlikti tai, kam jie sukurti: užtikrinti saugaus kodavimo standartus, aptikti paprastas problemas nuo šaltinio iki imtuvo ir dideliu mastu rasti žinomus šablonus su nuspėjamais kompromisais. Jie gali būti stipri visapusiškos gynybos dalis.

Šis įrašas yra siauresnis: jis apie tai, kodėl agentas, sukurtas protauti apie elgseną ir patvirtinti radinius, neturėtų pradėti savo darbo prisirišęs prie statinio radinių sąrašo.

Taip pat verta paminėti susijusį gryno mąstymo „nuo šaltinio iki duomenų gavėjo“ apribojimą: ne kiekvienas pažeidžiamumas yra duomenų srauto problema. Dauguma tikrų nesėkmių yra būsenos ir invariantų problemos – darbo eigos apėjimai, autorizacijos spragos ir klaidos „sistema yra netinkamos būsenos“. Tokioms klaidoms užteršta reikšmė nepasiekia vieno „pavojingo duomenų gavėjo“. Rizika slypi programos daromose prielaidose apie tai, kas visada turėtų būti teisinga. 

Ateities perspektyvos

Tikimės, kad saugumo įrankių ekosistema toliau tobulės: statinė analizė, „fuzzing“ (testavimas atsitiktiniais duomenimis), vykdymo laiko apsaugos ir agentų darbo eigos – visos jos turės savo vaidmenį.

Norime, kad „Codex Security“ puikiai atliktų tai, kas saugumo komandoms kainuoja brangiausiai: paverstų „tai atrodo įtartina“ į „tai tikra, štai kaip tai sugenda ir štai sistemos paskirtį atitinkantis pataisymas“. 

Jei norite sužinoti daugiau apie tai, kaip „Codex Security“ nuskaito saugyklas, patvirtina radinius ir siūlo pataisymus, žr. mūsų dokumentaciją(atsidaro naujame lange).

Autorius

OpenAI