Со децении, статичкото тестирање на безбедноста на апликации (SAST) е еден од најефикасните начини на кои безбедносните тимови го скалираат прегледот на код.
Но кога го изградивме Codex Security, направивме намерен избор во дизајнот: не почнавме со увезување извештај од статичка анализа и да го замолиме агентот да го тријажира. Го дизајниравме системот да започне со самиот репозиториум - неговата архитектура, границите на доверба и предвиденото однесување - и да го валидира она што ќе го пронајде пред да побара од човек да потроши време на тоа.
Причината е едноставна: најтешките ранливости обично не се проблеми со проток на податоци. Се случуваат кога кодот изгледа како да спроведува безбедносна проверка, но таа проверка всушност не го гарантира својството на кое се потпира системот. Со други зборови, предизвикот не е само да се следи како податоците се движат низ програмата - туку да се утврди дали одбраната во кодот навистина функционира.
SAST често се претставува како чиста постапка: идентификувај извор на недоверлив влез, следи ги податоците низ програмата и означи ги случаите каде што тие податоци стигнуваат до чувствително одредиште без санитизација. Тоа е елегантен модел и покрива многу вистински грешки.
Во пракса, SAST мора да прави апроксимации за да остане обработлив на големо - особено во реални бази на кодови со индиректно, динамичко испраќање, повратни повици, рефлексија и контролен тек базиран на рамка. Тие апроксимации не се удар врз SAST; тие се реалноста на обидот да се расудува за кодот без да се изврши.
Тоа, само по себе, не е причината зошто Codex Security не започнува со извештајот за SAST.
Подлабокото прашање е што се случува откако успешно ќе го проследите изворот до одредиштето.
Дури и кога статичката анализа правилно го следи внесувањето низ повеќе функции и слоеви, таа сепак мора да одговори на прашањето што всушност одредува дали постои ранливост:
Земете една вообичаена шема: кодот повикува нешто како sanitize_html() пред да прикаже недоверлива содржина. Статички анализатор може да види дека санитизаторот се извршил. Она што обично не може да го утврди е дали тој санитизатор е всушност доволен за конкретниот контекст на рендерирање, двигателот на шаблонот, однесувањето на кодирањето и вклучените надолни трансформации.
Тука работите се комплицираат. Проблемот не е само дали податоците стигнуваат до крајната точка. Прашањето е дали проверките во кодот навистина ја ограничуваат вредноста на начинот на кој системот претпоставува дека го прават.
Поинаку кажано: има голема разлика помеѓу „кодот повикува санитизатор“ и „системот е безбеден.“
Еве еден образец што често се појавува во реални системи.
Веб-апликација прима JSON payload, извлекува redirect_url, го проверува според дозволен regex, го декодира URL и го проследува резултатот до обработувачот за пренасочување.
Класичен извештај од извор до одредиште може да го опише текот:
недоверлив влез → проверка со регуларен израз → декодирање на URL → пренасочување
Но вистинското прашање не е дали проверката постои. Прашањето е дали таа проверка сè уште ја ограничува вредноста по трансформациите што следуваат.
Ако regex се извршува пред декодирањето, дали навистина го ограничува декодираниот URL на начинот на кој го толкува обработувачот за пренасочување?
Одговарањето на тоа значи расудување за целиот синџир на трансформација: што дозволува regex-от, како се однесуваат декодирањето и нормализацијата, како URL парсирањето ги третира граничните случаи и како логиката за пренасочување ги разрешува шемите и авторитетите.
Многу од ранливостите што се важни во практика изгледаат вака: грешки во редоследот на операциите, делумна нормализација, нејасности при парсирање и несовпаѓања меѓу валидацијата и толкувањето. Протокот на податоци е видлив. Слабоста е во тоа како ограничувањата се пренесуваат - или не успеваат да се пренесат - во целиот синџир на трансформација.
Ова не е само теоретски образец. Во CVE-2024-29041(се отвора во нов прозорец), Express беше засегнат од проблем со отворено пренасочување каде што неправилно формирани URL-адреси можеа да ги заобиколат вообичаените имплементации на листа на дозволени поради начинот на кој целите на пренасочувањето беа кодирани, а потоа и толкувани. Текот на податоците беше едноставен. Потешкото прашање - и она што утврди дали постоеше грешка - беше дали валидацијата сè уште важи по синџирот на трансформации.
Codex Security е изградена врз едноставна цел: да се намали тријажата преку откривање проблеми со посилни докази. Во производот, тоа значи користење на контекст специфичен за репозиториумот (вклучувајќи модел на закани) и валидирање на проблеми со висок сигнал во изолирана средина пред нивното откривање.
Кога Codex Security ќе наиде на граница што изгледа како „валидација“ или „санирање“, не го третира тоа како обележување. Се обидува да разбере што кодот се обидува да гарантира, а потоа се обидува да ја побие таа гаранција.
Во пракса, ова обично изгледа како комбинација од:
- Читање на релевантната патека на кодот со целосен контекст на репозиториумот, како што би направил истражувач за безбедност, и барање на несовпаѓања помеѓу намерата и имплементацијата. Ова вклучува коментари, но моделот не мора да им верува на коментарите, па додавањето //Halvar вели: ова не е грешка над вашиот код не го збунува, ако навистина има грешка.
- Сведување на проблемот на најмалиот тестирачки дел (на пример, процесот на трансформација околу еден единечен влез), за да можете да расудувате за него без остатокот од системот да ви пречи. Во оваа смисла, Codex Security извлекува ситни исечоци од код и потоа пишува микро-тестери со случајни податоци за нив.
- Расудување за ограничувања низ трансформации, наместо секоја проверка да се третира независно. Каде што е соодветно, ова може да вклучува формализација како прашање за задоволување. Со други зборови, му даваме на моделот пристап до Python околина со z3-solver и тој е вешт во користењето кога е потребно, исто како што би морал човек кога одговара на особено сложен проблем со ограничувања на влезните услови. Ова е особено корисно за анализа на прелевања на цели броеви или слични грешки на нестандардни архитектури.
- Извршување хипотези во контролирана средина за валидација, кога е можно, за да се разликува „ова може да биде проблем“ од „ова е проблем“. Нема подобар доказ од целосен PoC од крај до крај со кодот компајлиран во режим на дебагирање.
Ова е клучната промена: наместо да се застане кај „постои проверка“, системот нè насочува кон „инваријантата важи (или не важи), и еве ги доказите“. И моделот ја избира најдобрата алатка за таа задача.
Разумна реакција е: зошто да не ги направиме и двете работи? Започни со извештајот за SAST, а потоа користи го агентот за подлабоко размислување.
Постојат случаи кога претходно пресметаните наоди се корисни, особено за тесни и познати класи на грешки. Но, за агент дизајниран да открива и потврдува ранливости во контекст, започнувањето од извештај за SAST создава три предвидливи начини на неуспех.
Прво, тоа може да поттикне прерано стеснување. Списокот на наоди е мапа на местата каде што алатката веќе пребарувала. Ако го третирате како почетна точка, можете да го наклоните системот кон вложување непропорционален напор во истите региони, користејќи ги истите апстракции, и да пропуштите класи на проблеми што не се вклопуваат во светогледот на алатката.
Второ, може да воведе имплицитни судови кои е тешко да се разјаснат. Многу наоди од SAST содржат претпоставки за прочистување, проверка или граници на доверба. Ако тие претпоставки се погрешни - или само нецелосни - нивното внесување во циклусот на расудување може да го префрли агентот од „истражувај“ во „потврди или отфрли“, што не е она што го сакаме од агентот.
Трето, може да го отежни оценувањето на системот за расудување. Ако процесот започне со излез од SAST, станува тешко да се разграничи што агент открил преку сопствената анализа од она што го наследил од друга алатка. Тоа раздвојување е важно ако сакате точно да ги измерите способностите на системот, што е потребно за системот да се подобрува со текот на времето.
Затоа го создадовме Codex Security за да започнеме од таму каде што започнува безбедносното истражување: од кодот и намерата на системот, со валидација што се користи за зголемување на прагот на доверба пред да го прекинеме човекот.
Алатките за SAST можат да бидат одлични за она за што се наменети: спроведување стандарди за безбедно кодирање, откривање едноставни проблеми од извор до одредиште (sink) и препознавање познати обрасци во голем обем, со предвидливи компромиси. Тие можат да бидат силен дел од одбраната во длабочина.
Оваа објава е потесна: станува збор за тоа зошто агент дизајниран да расудува за однесувањето и да ги потврдува наодите не треба да ја започне својата работа закотвен за статична листа на наоди.
Исто така, вреди да се истакне едно поврзано ограничување на исклучиво размислување „од извор до одредиште“: не секоја ранливост е проблем со проток на податоци. Многу реални пропусти се проблеми со состојби и инваријанти - заобиколувања на работниот тек, празнини во овластувањето и грешки од типот „системот е во погрешна состојба“. За овие типови грешки, „загадена“ вредност не стигнува до ниту едно „опасно одредиште“. Ризикот е во тоа што програмата претпоставува дека нешто секогаш е точно.
Очекуваме екосистемот на безбедносни алатки да продолжи да се подобрува: статичка анализа, тестирање со случајни податоци, заштити при извршување и агентски работни процеси ќе имаат важни улоги.
Она во што сакаме Codex Security да биде најдобар е токму делот што најмногу ги чини безбедносните тимови: да го претвори „ова изгледа сомнително“ во „ова е реално, еве како откажува и еве поправка што се усогласува со намерата на системот.“
Ако сакате да дознаете повеќе за тоа како Codex Security ги скенира репозиториумите, ги валидира наодите и предлага поправки, погледнете ја нашата документација(се отвора во нов прозорец).


