स्किप करके मेन कंटेंट पर जाऍं
OpenAI

Codex Security में SAST रिपोर्ट क्यों शामिल नहीं है

दशकों से, स्टैटिक एप्लिकेशन सिक्योरिटी टेस्टिंग (SAST) सिक्योरिटी टीम्स के लिए कोड रिव्यू को स्केल करने के सबसे प्रभावी तरीकों में से एक रहा है.

लेकिन जब हमने Codex Security बनाया, तो हमने सोच-समझकर एक डिज़ाइन निर्णय लिया: हमने स्टैटिक एनालिसिस रिपोर्ट इम्पोर्ट करके एजेंट से उसे ट्रायेज करने से शुरुआत नहीं की. हमने सिस्टम को इस तरह डिज़ाइन किया कि वह सीधे रिपॉजिटरी से शुरू करे—उसकी आर्किटेक्चर, ट्रस्ट बाउंड्रीज़ और इंटेंडेड बिहेवियर को समझे—और जो भी वह पाए, उसे पहले वैलिडेट करे, फिर ही किसी इंसान से समय देने को कहे.

वजह सरल है: सबसे कठिन वल्नरेबिलिटीज़ आमतौर पर डेटा फ्लो की समस्याएँ नहीं होतीं. वे तब होती हैं जब कोड ऐसा लगता है कि वह सिक्योरिटी चेक लागू कर रहा है, लेकिन वह चेक वास्तव में उस प्रॉपर्टी की गारंटी नहीं देता जिस पर सिस्टम निर्भर करता है. दूसरे शब्दों में, चुनौती सिर्फ यह ट्रैक करना नहीं है कि डेटा प्रोग्राम में कैसे चलता है—बल्कि यह तय करना है कि कोड में मौजूद डिफेंस वास्तव में काम करते हैं या नहीं.

समस्या: SAST डेटा फ्लो के लिए ऑप्टिमाइज़ किया गया है

SAST को अक्सर एक साफ पाइपलाइन की तरह समझाया जाता है: अनट्रस्टेड इनपुट का सोर्स पहचानें, प्रोग्राम में डेटा के फ्लो को ट्रैक करें, और उन मामलों को फ्लैग करें जहाँ यह डेटा बिना सैनिटाइजेशन के किसी सेंसिटिव सिंक तक पहुँचता है. यह एक सलीकेदार मॉडल है और कई वास्तविक बग्स को कवर करता है.

व्यवहार में, SAST को स्केल पर काम करने योग्य बने रहने के लिए कुछ अनुमान लगाने पड़ते हैं—खासतौर पर उन वास्तविक कोडबेस में जहाँ इंडायरेक्शन, डायनेमिक डिस्पैच, कॉलबैक्स, रिफ्लेक्शन और फ्रेमवर्क-हेवी कंट्रोल फ्लो होते हैं. ये अनुमान SAST की कमी नहीं हैं; बल्कि यह उस वास्तविकता को दर्शाते हैं कि कोड को बिना चलाए उसके बारे में रीज़न करना पड़ता है.

यही अकेला कारण नहीं है कि Codex Security SAST रिपोर्ट से शुरुआत नहीं करता.

असली समस्या यह है कि जब आप किसी सोर्स से सिंक तक ट्रेस कर लेते हैं, उसके बाद क्या होता है.

जहाँ स्टैटिक एनालिसिस को दिक्कत होती है: कंस्ट्रेंट्स और सेमांटिक्स

भले ही स्टैटिक एनालिसिस कई फंक्शन्स और लेयर्स में इनपुट को सही तरीके से ट्रेस कर ले, फिर भी उसे उस सवाल का जवाब देना होता है जो वास्तव में तय करता है कि वल्नरेबिलिटी है या नहीं:

क्या सुरक्षा उपाय वास्तव में काम किया?

एक आम पैटर्न लें: अनट्रस्टेड कंटेंट को रेंडर करने से पहले कोड sanitize_html() जैसी किसी फ़ंक्शन को कॉल करता है. एक स्टैटिक एनालाइज़र देख सकता है कि सैनिटाइज़र चला. लेकिन यह आमतौर पर यह तय नहीं कर पाता कि वह सैनिटाइज़र खास रेंडरिंग कॉन्टेक्स्ट, टेम्पलेट इंजन, एन्कोडिंग व्यवहार और डाउनस्ट्रीम ट्रांसफॉर्मेशन्स के लिए वास्तव में पर्याप्त है या नहीं.

यहीं चीज़ें मुश्किल हो जाती हैं. समस्या सिर्फ यह नहीं है कि डेटा किसी सिंक तक पहुँचता है या नहीं. बल्कि यह है कि कोड में किए गए चेक्स वास्तव में वैल्यू को उसी तरह सीमित करते हैं या नहीं जैसा सिस्टम मानता है.

दूसरे शब्दों में कहें: “कोड sanitizer को कॉल करता है” और “सिस्टम सुरक्षित है.” के बीच बड़ा अंतर है.

उदाहरण: डिकोडिंग से पहले वैलिडेशन

यह एक पैटर्न है जो वास्तविक सिस्टम्स में अक्सर देखने को मिलता है.

एक वेब एप्लिकेशन JSON payload प्राप्त करता है, उसमें से redirect_url निकालता है, उसे allowlist regex के खिलाफ वैलिडेट करता है, फिर URL-डिकोड करता है और परिणाम को रीडायरेक्ट हैंडलर को भेज देता है.

एक क्लासिक सोर्स-टू-सिंक रिपोर्ट इस फ्लो को इस तरह दिखा सकती है:

अनट्रस्टेड इनपुट → regex चेक → URL डिकोड → रीडायरेक्ट

लेकिन असली सवाल यह नहीं है कि जाँच मौजूद है या नहीं. असली बात यह है कि बाद में होने वाले रूपांतरणों के बाद भी वह जाँच मान को सीमित रखती है या नहीं.

अगर रेगुलर एक्सप्रेशन डिकोडिंग से पहले चलता है, तो क्या यह वास्तव में डिकोड किया गया URL को उसी तरह सीमित करता है जैसा रीडायरेक्ट हैंडलर उसे समझता है?

इसका जवाब देने के लिए पूरे रूपांतरण श्रृंखला पर रीज़न करना पड़ता है: regex क्या अनुमति देता है, डिकोडिंग और नॉर्मलाइज़ेशन कैसे व्यवहार करते हैं, URL पार्सिंग किन एज केसों को कैसे संभालती है, और रीडायरेक्ट लॉजिक स्कीम्स और अथॉरिटीज़ को कैसे रिज़ॉल्व करता है.

व्यवहार में महत्वपूर्ण कई कमजोरियाँ ऐसी ही होती हैं: क्रम-प्रक्रिया की गलतियाँ, आंशिक नॉर्मलाइज़ेशन, पार्सिंग में अस्पष्टता, और वैलिडेशन और इंटरप्रिटेशन के बीच असंगति. डेटा फ्लो स्पष्ट दिखाई देता है. कमजोरी इस बात में होती है कि रूपांतरण श्रृंखला के दौरान कंस्ट्रेंट्स कैसे फैलते हैं—या फैलने में कहाँ विफल हो जाते हैं.

यह केवल एक सैद्धांतिक पैटर्न नहीं है. CVE-2024-29041(एक नई विंडो में खुलेगा) में, Express एक ओपन रीडायरेक्ट समस्या से प्रभावित था, जहाँ गलत तरीके से बने URL आम अलाउलिस्ट इम्प्लीमेंटेशन को बायपास कर सकते थे, क्योंकि रीडायरेक्ट टार्गेट्स को एन्कोड करने और बाद में इंटरप्रेट करने का तरीका ऐसा था. डेटा फ्लो सीधा था. कठिन सवाल—और वही जो तय करता था कि बग मौजूद है या नहीं—यह था कि रूपांतरण श्रृंखला के बाद भी वैलिडेशन कायम रहता है या नहीं.

हमारा अप्रोच: बिहेवियर से शुरू करें, फिर वैलिडेट करें

Codex Security एक सरल लक्ष्य पर बनाया गया है: मजबूत सबूतों के साथ समस्याओं को सामने लाकर ट्रायेज को कम करना. प्रॉडक्ट में इसका मतलब है रिपो-विशिष्ट कॉन्टेक्स्ट (जिसमें थ्रेट मॉडल भी शामिल है) का उपयोग करना और हाई-सिग्नल समस्याओं को सामने लाने से पहले एक आइसोलेटेड एनवायरनमेंट में वैलिडेट करना.

जब Codex Security किसी ऐसी बाउंड्री पर आता है जो “वैलिडेशन” या “सैनिटाइजेशन,” जैसी दिखती है, तो वह उसे सिर्फ एक चेकबॉक्स की तरह नहीं लेता. वह यह समझने की कोशिश करता है कि कोड क्या गारंटी देने की कोशिश कर रहा है—और फिर उस गारंटी को गलत साबित करने की कोशिश करता है.

व्यवहार में, यह आमतौर पर इन चीज़ों के मिश्रण जैसा होता है:

  • पूरे रिपॉजिटरी कॉन्टेक्स्ट के साथ संबंधित कोड पाथ को पढ़ना, ठीक वैसे जैसे कोई सिक्योरिटी रिसर्चर करता है, और इंटेंट और इम्प्लीमेंटेशन के बीच मिसमैच ढूँढना. समें टिप्पणियाँ भी शामिल हैं, लेकिन मॉडल ज़रूरी नहीं कि टिप्पणियों पर भरोसा करे, इसलिए अपने कोड के ऊपर //Halvar कहते है: यह बग नहीं है जोड़ने से वह कन्फ्यूज़ नहीं होता, अगर सच में कोई बग हो.
  • समस्या को सबसे छोटे टेस्टेबल हिस्से तक सीमित करना (जैसे किसी एक इनपुट के आसपास का ट्रांसफॉर्मेशन पाइपलाइन), ताकि आप बाकी सिस्टम के बिना बाधा बने उस पर रीज़निंग कर सकें. इस तरह, Codex Security छोटे-छोटे कोड स्लाइस निकालता है और उनके लिए माइक्रो-फज़र्स लिखता है.
  • हर जाँच को अलग-अलग देखने के बजाय, ट्रांसफॉर्मेशन्स के पार कंस्ट्रेंट्स पर रीज़न करना. जहाँ उपयुक्त हो, इसे सैटिस्फ़ायबिलिटी प्रश्न के रूप में औपचारिक बनाया जा सकता है. दूसरे शब्दों में, हम मॉडल को z3-solver वाले Python एनवायरनमेंट का एक्सेस देते हैं, और जरूरत पड़ने पर वह इसका सही उपयोग करता है—ठीक वैसे ही जैसे कोई इंसान जटिल इनपुट कंस्ट्रेंट समस्या को हल करते समय करता है. यह खास तौर पर नॉन-स्टैंडर्ड आर्किटेक्चर्स पर integer overflow या ऐसे ही मिलते-जुलते बग्स को देखने के लिए बहुत उपयोगी है.
  • जहाँ संभव हो, सैंडबॉक्स्ड वैलिडेशन एनवायरनमेंट में हाइपोथीसिस को एक्सीक्यूट करना, ताकि “यह समस्या हो सकती है” और “यह वास्तव में समस्या है” के बीच फर्क किया जा सके. कोड को डिबग मोड में कंपाइल करके बनाया गया पूरा एंड-टू-एंड PoC से बेहतर कोई सबूत नहीं होता.

यही मुख्य बदलाव है: “जाँच मौजूद है” पर रुकने के बजाय, सिस्टम “इनवेरिएंट सही है (या नहीं है), और यह रहा उसका सबूत” तक पहुँचता है. और मॉडल उस काम के लिए सबसे सही टूल चुनता है.

हम Codex Security की शुरुआत SAST रिपोर्ट से क्यों नहीं करते

एक सामान्य सवाल है: दोनों क्यों न करें? SAST रिपोर्ट से शुरू करें, फिर एजेंट का उपयोग करके गहराई से रीज़न करें.

कुछ मामलों में पहले से निकाले गए निष्कर्ष उपयोगी होते हैं—खासतौर पर सीमित और ज्ञात बग क्लासेस के लिए. लेकिन ऐसे एजेंट के लिए जो कॉन्टेक्स्ट में वल्नरेबिलिटीज़ खोजने और वैलिडेट करने के लिए बनाया गया है, SAST रिपोर्ट से शुरुआत करना तीन सामान्य फेल्यर मोड्स पैदा करता है.

पहला, यह समय से पहले दायरा सीमित करने की प्रवृत्ति बढ़ा सकता है. फाइंडिंग्स की सूची यह दिखाने वाला एक मैप है कि टूल पहले कहाँ देख चुका है. अगर इसे शुरुआती बिंदु मान लिया जाए, तो सिस्टम उन्हीं हिस्सों में असमान रूप से ज़्यादा प्रयास करने लगता है, वही एब्स्ट्रैक्शन्स अपनाता है, और उन समस्याओं की श्रेणियाँ छूट जाती हैं जो टूल के दृष्टिकोण में फिट नहीं बैठतीं.

दूसरा, यह ऐसे इम्प्लिसिट जजमेंट्स ला सकता है जिन्हें बाद में बदलना मुश्किल होता है. कई SAST फाइंडिंग्स में सैनिटाइजेशन, वैलिडेशन या ट्रस्ट बाउंड्रीज़ के बारे में धारणाएँ शामिल होती हैं. अगर ये धारणाएँ गलत हों—या अधूरी हों—तो इन्हें रीज़निंग लूप में डालने से एजेंट “जांच करने” के बजाय “पुष्टि या खारिज करने” की दिशा में चला जाता है, जो हम नहीं चाहते.

तीसरा, यह रीज़निंग सिस्टम का मूल्यांकन करना और कठिन बना सकता है. अगर पाइपलाइन SAST आउटपुट से शुरू होती है, तो यह अलग करना मुश्किल हो जाता है कि एजेंट ने खुद के एनालिसिस से क्या खोजा और क्या किसी दूसरे टूल से लिया. यह अलगाव ज़रूरी है ताकि सिस्टम की क्षमताओं को सही तरीके से मापा जा सके, जो समय के साथ सुधार के लिए आवश्यक है.

इसलिए हमने Codex Security को वहीं से शुरू करने के लिए बनाया जहाँ सिक्योरिटी रिसर्च शुरू होती है: कोड और सिस्टम के इंटेंट से, और किसी इंसान को शामिल करने से पहले कॉन्फिडेंस लेवल बढ़ाने के लिए वैलिडेशन का उपयोग किया जाता है.

SAST टूल्स अभी भी बहुत महत्वपूर्ण हैं

SAST टूल्स अपने तय काम में बेहतरीन हो सकते हैं: सुरक्षित कोडिंग मानकों को लागू करना, सीधे-सादे सोर्स-टू-सिंक समस्याओं को पकड़ना, और ज्ञात पैटर्न्स को बड़े पैमाने पर अनुमानित समझौतों के साथ पहचानना. ये डिफेंस-इन-डेप्थ रणनीति का एक मजबूत हिस्सा हो सकते हैं.

यह पोस्ट सीमित फोकस वाला है: इसमें बताया गया है कि व्यवहार पर रीज़निंग करने और फाइंडिंग्स को वैलिडेट करने के लिए बनाए गए एजेंट को अपना काम किसी स्टैटिक फाइंडिंग्स सूची पर आधारित करके शुरू क्यों नहीं करना चाहिए.

यह भी बताना ज़रूरी है कि केवल सोर्स-टू-सिंक सोच की एक संबंधित सीमा है: हर वल्नरेबिलिटी डेटा फ्लो समस्या नहीं होती. कई वास्तविक विफलताएँ स्टेट और इनवेरिएंट से जुड़ी समस्याएँ होती हैं—वर्कफ़्लो बायपास, ऑथराइजेशन गैप्स, और “सिस्टम गलत स्टेट में है” जैसे बग्स. ऐसे बग्स में, दूषित मान किसी एक “खतरनाक सिंक” तक नहीं पहुँचता. जोखिम इस बात में होता है कि प्रोग्राम क्या मानकर चलता है कि हमेशा सही रहेगा.

आगे का विज़न

हमें उम्मीद है कि सिक्योरिटी टूलिंग इकोसिस्टम आगे भी बेहतर होता रहेगा: स्टैटिक एनालिसिस, फज़िंग, रनटाइम गार्ड्स और एजेंटिक वर्कफ्लो—सभी की अपनी भूमिका होगी.

हम चाहते हैं कि Codex Security उस हिस्से में मजबूत हो जो सिक्योरिटी टीम्स के लिए सबसे महंगा पड़ता है: “यह संदिग्ध लगता है” को “यह वास्तविक है, यह ऐसे फेल होता है, और यह रहा सिस्टम के इंटेंट से मेल खाता समाधान” में बदलना.

अगर आप जानना चाहते हैं कि Codex Security रिपॉजिटरीज़ को कैसे स्कैन करता है, फाइंडिंग्स को कैसे वैलिडेट करता है, और फिक्स कैसे सुझाता है, तो हमारा डॉक्यूमेंटेशन(एक नई विंडो में खुलेगा) देखें.

लेखक

OpenAI