દાયકાઓથી, static application security testing (SAST) સુરક્ષા ટીમો માટે code review ને વ્યાપક સ્તરે ચલાવવાના સૌથી અસરકારક રસ્તાઓમાંનું એક રહ્યું છે.
પરંતુ જ્યારે અમે Codex Security બનાવ્યું, ત્યારે અમે ઇરાદાપૂર્વકનો ડિઝાઇન નિર્ણય લીધો: અમે static analysis report આયાત કરીને અને એજન્ટને તેનું triage કરવા કહીને શરૂઆત કરી નહોતી. અમે સિસ્ટમને રિપોઝિટરીથી જ શરૂઆત કરવા માટે રચી—તેની architecture, trust boundaries અને intended behavior પરથી—અને માનવીને તેમાં સમય ખર્ચવા કહે તે પહેલાં તે જે શોધે છે તેની ચકાસણી કરે તેવી રીતે બનાવ્યું.
કારણ સરળ છે: સૌથી કઠિન નબળાઈઓ સામાન્ય રીતે dataflow સમસ્યાઓ નથી. તે ત્યારે બને છે જ્યારે code કોઈ security check લાગુ કરતું હોય એવું લાગે છે, પરંતુ તે check હકીકતમાં સિસ્ટમ જે ગુણધર્મ પર નિર્ભર છે તેની ખાતરી આપતું નથી. બીજા શબ્દોમાં કહીએ તો, પડકાર માત્ર એટલો નથી કે data પ્રોગ્રામમાં કેવી રીતે પસાર થાય છે તે ટ્રેક કરવો—પરંતુ code માંની સુરક્ષા વ્યવસ્થાઓ ખરેખર કામ કરે છે કે નહીં તે નક્કી કરવું છે.
SAST ને ઘણી વાર એક સ્વચ્છ pipeline તરીકે રજૂ કરવામાં આવે છે: અવિશ્વસનીય input નો source ઓળખો, data ને program મારફતે ટ્રેક કરો, અને જ્યાં એ data sanitization વિના sensitive sink સુધી પહોંચે તે કેસોને flag કરો. આ એક સુંદર મોડેલ છે, અને તે ઘણા વાસ્તવિક bugs આવરી લે છે.
હકીકતમાં, SAST ને scale પર કાર્યક્ષમ રાખવા માટે approximation કરવી પડે છે—ખાસ કરીને એવા વાસ્તવિક codebases માં જ્યાં indirection, dynamic dispatch, callbacks, reflection અને framework-heavy control flow હોય. આ approximations SAST ની ખામી નથી; code ચલાવ્યા વિના તેના વિશે reasoning કરવાનો પ્રયાસ કરવાના વાસ્તવિક પરિણામ છે.
માત્ર આ જ કારણ નથી કે Codex Security ની શરૂઆત SAST રિપોર્ટથી થતી નથી.
વધુ ઊંડો મુદ્દો એ છે કે source થી sink સુધીનો માર્ગ સફળતાપૂર્વક ટ્રેસ કર્યા પછી શું બને છે.
ભલે static analysis ઇનપુટને અનેક functions અને layers માંથી યોગ્ય રીતે ટ્રેસ કરે, છતાં તેને એ પ્રશ્નનો જવાબ આપવો જ પડે છે જે હકીકતમાં નક્કી કરે છે કે નબળાઈ છે કે નહીં:
એક સામાન્ય pattern લો: code અવિશ્વસનીય content render કરતાં પહેલાં sanitize_html() જેવી કોઈ વસ્તુને call કરે છે. Static analyzer જોઈ શકે છે કે sanitizer ચાલ્યો હતો. પરંતુ સામાન્ય રીતે તે નક્કી કરી શકતું નથી કે સામેલ ચોક્કસ rendering context, template engine, encoding behavior અને downstream transformations માટે એ sanitizer ખરેખર પૂરતો છે કે નહીં.
અહીંથી વસ્તુઓ મુશ્કેલ બને છે. પ્રશ્ન માત્ર એટલો નથી કે data sink સુધી પહોંચે છે કે નહીં. પ્રશ્ન એ છે કે code માંના checks ખરેખર value ને એ રીતે constrain કરે છે કે નહીં જેમ સિસ્ટમ માન્ય રાખે છે.
બીજી રીતે કહીએ તો: “code sanitizer ને call કરે છે” અને “સિસ્ટમ સુરક્ષિત છે.” વચ્ચે મોટો ફરક છે.
આવો એક pattern છે જે વાસ્તવિક systems માં સતત જોવા મળે છે.
એક web application JSON payload મેળવે છે, redirect_url કાઢે છે, તેને allowlist regex સામે validate કરે છે, URL-decode કરે છે, અને પરિણામને redirect handler ને આપે છે.
એક પરંપરાગત source-to-sink report flow નું વર્ણન કરી શકે છે:
untrusted input → regex check → URL decode → redirect
પરંતુ વાસ્તવિક પ્રશ્ન એ નથી કે check અસ્તિત્વમાં છે કે નહીં. પ્રશ્ન એ છે કે પછી આવતા transformations પછી પણ એ check value ને constrain કરે છે કે નહીં.
જો regex decoding પહેલાં ચાલે, તો શું તે redirect handler જે રીતે decoded URL ને સમજે છે તે રીતે તેને ખરેખર constrain કરે છે?
આનો જવાબ આપવા માટે સમગ્ર transformation chain વિશે reasoning કરવું પડે: regex શું મંજૂર કરે છે, decoding અને normalization કેવી રીતે વર્તે છે, URL parsing edge cases ને કેવી રીતે હેન્ડલ કરે છે, અને redirect logic schemes અને authorities ને કેવી રીતે resolve કરે છે.
વ્યવહારમાં મહત્વ ધરાવતી ઘણી નબળાઈઓ આવી જ હોય છે: order-of-operations ની ભૂલો, partial normalization, parsing ambiguities અને validation અને interpretation વચ્ચેના mismatches. Dataflow દેખાય છે. કમજોરી એમાં છે કે constraints transformation chain મારફતે કેવી રીતે propagate થાય છે—અથવા થવામાં નિષ્ફળ જાય છે.
આ માત્ર સિદ્ધાંતમાં જોવા મળતો pattern નથી. CVE-2024-29041(નવી વિન્ડોમાં ખૂલે છે) માં Express open redirect સમસ્યાથી પ્રભાવિત થયું હતું, જ્યાં malformed URLs સામાન્ય allowlist implementations ને bypass કરી શકતા હતા, કારણ કે redirect targets કેવી રીતે encode થયા અને પછી કેવી રીતે interpret થયા. Dataflow સીધો હતો. વધુ કઠિન પ્રશ્ન—અને જે નક્કી કરતો હતો કે bug અસ્તિત્વમાં હતો કે નહીં—એ હતો કે transformation chain પછી પણ validation યથાવત્ રહે છે કે નહીં.
Codex Security એક સરળ લક્ષ્યને ધ્યાનમાં રાખીને બનાવવામાં આવ્યું છે: વધુ મજબૂત પુરાવા સાથે issues સપાટી પર લાવીને triage ઘટાડવું. ઉત્પાદન સ્તરે તેનો અર્થ છે repo-specific context (જેમાં threat model પણ શામેલ છે) નો ઉપયોગ કરવો અને high-signal issues ને સપાટી પર લાવવા પહેલાં અલગ પડેલા environment માં validate કરવું.
જ્યારે Codex Security ને “validation” અથવા “sanitization” જેવી કોઈ boundary મળે છે, ત્યારે તે તેને માત્ર checkbox તરીકે લેતું નથી. તે સમજવાનો પ્રયાસ કરે છે કે code શું ગેરંટી આપવાનો પ્રયાસ કરે છે—અને પછી એ ગેરંટી ખોટી સાબિત કરવાનો પ્રયત્ન કરે છે.
વ્યવહારમાં, આ સામાન્ય રીતે નીચે મુજબના મિશ્રણ જેવું લાગે છે:
- સંબંધિત code path ને સંપૂર્ણ રિપોઝિટરી context સાથે વાંચવું, જેમ કોઈ security researcher વાંચે, અને intent અને implementation વચ્ચે mismatch શોધવું. તેમાં comments પણ શામેલ છે, પરંતુ મોડલ comments પર આવશ્યક નહીં કે વિશ્વાસ કરે, તેથી તમારા code ઉપર //Halvar says: this is not a bug ઉમેરવાથી, જો ખરેખર bug હશે તો, તે ગૂંચવાતું નથી.
- સમસ્યાને સૌથી નાની testable slice સુધી સીમિત કરવી (ઉદાહરણ તરીકે, એક જ input ની આસપાસની transformation pipeline), જેથી બાકી સિસ્ટમ વચ્ચે ન આવે અને તેના વિશે reasoning કરી શકાય. આ અર્થમાં, Codex Security નાના code slices અલગ કરે છે અને પછી તેમના માટે micro-fuzzers લખે છે.
- દરેક check ને સ્વતંત્ર રીતે જોવાને બદલે transformations દરમ્યાન constraints વિશે reasoning કરવું. જ્યાં યોગ્ય હોય ત્યાં આને satisfiability પ્રશ્ન તરીકે formalize પણ કરી શકાય. બીજા શબ્દોમાં કહીએ તો, અમે મોડલને z3-solver ધરાવતા Python environment નો પ્રવેશ આપીએ છીએ અને જરૂરી હોય ત્યારે તે તેનો સારો ઉપયોગ કરે છે, બરાબર એમ જ જેમ કોઈ માનવીને ખાસ જટિલ input constraint સમસ્યાનો જવાબ આપવા માટે કરવું પડે. non-standard architectures પર integer overflow અથવા સમાન bugs જોવા માટે આ ખાસ ઉપયોગી છે.
- શક્ય હોય ત્યારે sandboxed validation environment માં hypotheses ચલાવવી, જેથી “આ સમસ્યા હોઈ શકે” અને “આ ખરેખર સમસ્યા છે” વચ્ચે ભેદ કરી શકાય. debug mode માં compile કરેલા code સાથેની સંપૂર્ણ end-to-end PoC કરતાં સારો પુરાવો બીજો નથી.
આ મુખ્ય ફેરફાર છે: “check અસ્તિત્વમાં છે” પર અટકી જવાને બદલે, સિસ્ટમ “invariant સાચું રહે છે (અથવા રહેતું નથી), અને આ રહ્યો પુરાવો” તરફ આગળ ધપે છે. અને આ કામ માટે મોડલ સૌથી યોગ્ય tool પસંદ કરે છે.
યોગ્ય પ્રતિક્રિયા આવી હોઈ શકે: બન્ને કેમ નહીં? SAST રિપોર્ટથી શરૂઆત કરો, પછી એજન્ટને વધુ ઊંડું reasoning કરવા દો.
કેટલાક કેસોમાં પૂર્વગણિત findings મદદરૂપ થાય છે—ખાસ કરીને સીમિત અને જાણીતા bug classes માટે. પરંતુ context માં vulnerabilities શોધવા અને validate કરવા માટે રચાયેલા એજન્ટ માટે SAST રિપોર્ટથી શરૂઆત કરવાથી ત્રણ અનુમાનિત failure modes ઊભા થાય છે.
પ્રથમ, તે સમય પહેલાં જ scope ને સાંકડો બનાવવાનું પ્રોત્સાહન આપી શકે છે. Findings list એ નકશો છે કે tool પહેલેથી ક્યાં જોઈ ગયું છે. જો તમે તેને શરૂઆતનો બિંદુ માનો, તો સિસ્ટમ એ જ વિસ્તારોમાં, એ જ abstractions સાથે, અસંગત પ્રમાણમાં વધુ પ્રયત્ન કરવા તરફ પક્ષપાતી બની શકે છે અને તેવા issue classes ચૂકી શકે છે જે tool ની worldview સાથે બંધબેસતા નથી.
બીજું, તે એવા implicit judgments દાખલ કરી શકે છે જેને પાછા ઉકેલવા મુશ્કેલ હોય. ઘણા SAST findings sanitization, validation અથવા trust boundaries વિશેની માન્યતાઓ એન્કોડ કરે છે. જો એ માન્યતાઓ ખોટી હોય—અથવા ફક્ત અધૂરી હોય—તો reasoning loop માં તેમને આપવાથી એજન્ટ “તપાસ કરો” માંથી “પુષ્ટિ કરો અથવા નકારો” તરફ વળી શકે છે, અને અમે એજન્ટ પાસે આવું કરાવવું નથી માંગતા.
ત્રીજું, તે reasoning system નું મૂલ્યાંકન કરવું વધુ મુશ્કેલ બનાવી શકે છે. જો pipeline ની શરૂઆત SAST output થી થાય, તો એજન્ટે પોતાની વિશ્લેષણથી શું શોધ્યું અને બીજા tool પાસેથી શું વારસામાં મેળવ્યું તે અલગ પાડવું મુશ્કેલ બની જાય છે. જો તમે સિસ્ટમની ક્ષમતાઓને ચોક્કસપણે માપવા માંગતા હો તો આ ભેદ મહત્વનો છે, અને સમય સાથે સિસ્ટમ સુધરે તે માટે પણ તે જરૂરી છે.
એ કારણે અમે Codex Security ને ત્યાંથી શરૂ થાય એવી રીતે બનાવ્યું જ્યાં security research શરૂ થાય છે: code અને સિસ્ટમના intent પરથી, અને validation નો ઉપયોગ માનવીને interrupt કરીએ તે પહેલાં confidence bar ઊંચી કરવા માટે થાય છે.
SAST tools તેઓ જે માટે રચાયા છે તેમાં ઉત્તમ હોઈ શકે છે: secure coding standards અમલમાં મૂકવા, સરળ source-to-sink issues પકડવા, અને જાણીતા patterns ને scale પર અનુમાનનીય tradeoffs સાથે શોધવા. તેઓ defense-in-depth નો મજબૂત ભાગ બની શકે છે.
આ પોસ્ટ વધુ સીમિત છે: તેનો વિષય એ છે કે behavior વિશે reasoning કરવા અને findings validate કરવા માટે રચાયેલ એજન્ટે પોતાનું કામ static findings list સાથે બંધાયેલું રાખીને શરૂ ન કરવું જોઈએ.
શુદ્ધ source-to-sink વિચારસરણીની એક સંબંધિત મર્યાદા પણ નોંધપાત્ર છે: દરેક નબળાઈ dataflow સમસ્યા નથી. ઘણી વાસ્તવિક નિષ્ફળતાઓ state અને invariant સમસ્યાઓ છે—workflow bypasses, authorization gaps, અને “સિસ્ટમ ખોટી સ્થિતિમાં છે” પ્રકારના bugs. આવા bugs માં tainted value એક જ “dangerous sink” સુધી પહોંચતું નથી. જોખમ તેમાં છે કે program શું હંમેશા સાચું રહેશે એવી ધારણા રાખે છે.
અમને અપેક્ષા છે કે security tooling ecosystem સુધરતો રહેશે: static analysis, fuzzing, runtime guards અને agentic workflows બધાની ભૂમિકા રહેશે.
અમે Codex Security ને તેમાં સારો બનતો જોવા માંગીએ છીએ જે security teams માટે સૌથી વધુ ખર્ચાળ છે: “આ શંકાસ્પદ લાગે છે” ને “આ વાસ્તવિક છે, આ રીતે નિષ્ફળ જાય છે, અને આ રહ્યો સિસ્ટમના intent સાથે મેળ ખાતો fix.” માં બદલી દેવું.
જો તમે Codex Security રિપોઝિટરીઓ કેવી રીતે scan કરે છે, findings કેવી રીતે validate કરે છે, અને fixes કેવી રીતે સૂચવે છે તે વિશે વધુ જાણવા માંગતા હો, તો અમારું documentation(નવી વિન્ડોમાં ખૂલે છે) જુઓ.


