
अपनी attack surface के दृश्यों का क्रॉस-चेक करें और वे endpoints खोजें जो एक-दूसरे की पुष्टि नहीं कर सकते।
अपनी अटैक सरफेस के विचारों का क्रॉस-चेक करें और वे एंडपॉइंट्स खोजें जो एक-दूसरे की पुष्टि नहीं कर सकते।
एक एंडपॉइंट को अपना हिसाब देने में सक्षम होना चाहिए। यह कोड में है, इसलिए एक कॉन्ट्रैक्ट को इसका वर्णन करना चाहिए। यह कॉन्ट्रैक्ट में है, इसलिए किसी को इसे लागू करना चाहिए। यह वास्तविक ट्रैफ़िक लेता है, इसलिए बेहतर होगा कि यह कहीं मौजूद हो। जब एक विचार किसी एंडपॉइंट के बारे में जानता है और बाकी नहीं जानते, तो वह अंतर ही निष्कर्ष है।
alibi OWASP noir चलाता है, उसका JSON पढ़ता है, और विचारों की एक-दूसरे से तुलना करता है।
Noir पहले से ही एक ही सरफेस के पाँच स्वतंत्र विचार पढ़ता है:
| विचार | यहाँ से पढ़ा जाता है |
|---|---|
| code | 33 भाषाओं में 200 से अधिक विश्लेषक |
| doc | OpenAPI, RAML, WSDL, GraphQL SDL, AsyncAPI, gRPC, Smithy, TypeSpec, OData, OpenRPC |
| traffic | HAR, mitmproxy, Burp, Caido, ZAP, Postman, Insomnia, Bruno, .http |
| gateway | nginx, Apache, Envoy, Kong, Traefik, APISIX, Caddy, Istio, Kubernetes Ingress और Gateway API |
| infra | Terraform, CloudFormation, CDK, Serverless, Vercel, Netlify, Wrangler, Azure Functions, Kamal |
जो यह नहीं करता वह है उनकी तुलना करना। यहाँ पूरा काम यही है, और इसमें noir में किसी बदलाव की आवश्यकता नहीं है — alibi इसे प्रति विचार एक बार चलाता है और परिणामों को जोड़ता है।
प्रति-विचार वाला हिस्सा महत्वपूर्ण है। Noir हर विश्लेषक के बीच (method, url) के आधार पर डुप्लिकेट हटाता है, इसलिए एक Flask रूट और एक OpenAPI पथ जो एक जैसे लिखे गए हैं, एक ही एंडपॉइंट में समा जाते हैं जो एक ही तकनीक रखता है। यह एक डिस्कवरी टूल के लिए सही है — यह एक एंडपॉइंट है — लेकिन यह उस पुष्टि को मिटा देता है जिसे मापने के लिए यह टूल बनाया गया है, और इसे सबसे बुरी दिशा में मिटाता है: दो विचार जितने बेहतर सहमत होते हैं, उतने ही अधिक गायब हो जाते हैं। Casdoor 372 कोड एंडपॉइंट्स और 9 दस्तावेज़ित एंडपॉइंट्स के रूप में स्कैन होता है; अकेले इसकी swagger/ डायरेक्टरी स्कैन करें तो स्पेसिफिकेशन में 235 हैं।
--only-techs डिटेक्टर पूल को सीमित करता है, इसलिए प्रति विचार एक स्कैन हर एक को पूरा रखता है। कौन सी तकनीक किस विचार के लिए बोलती है यह views.yml है; कौन सी तकनीकें मौजूद हैं यह वही है जो noir list techs रिपोर्ट करता है।
alibi अपने स्वयं के किसी API फ़ॉर्मेट को पार्स नहीं करता। इसका एकमात्र इनपुट noir का JSON है।
PATH पर noir 1.0.0 या नया आवश्यक है -- यही वह रिलीज़ है जिसमें noir list techs एक सबकमांड बना, और वही कैटलॉग हर तकनीक को एक विचार को सौंपता है। डेवलपमेंट वर्तमान noir रिलीज़ को ट्रैक करता है। पुराने बाइनरी को नाम लेकर अस्वीकार कर दिया जाता है, बजाय इसके कि उसे उसकी पहली कैटलॉग रीड पर विफल होने के लिए छोड़ दिया जाए।
$ uv tool install noir-alibi # or: pipx install noir-alibi
$ alibi scan ./my-service
$ alibi scan # the working directory
$ alibi scan ./service ./contracts ./prod.har # or wherever the views live
हर पथ एक स्रोत है, जिसे प्रति दृश्य एक बार स्कैन किया जाता है। इसे आपके पास जो भी हो, उस पर इंगित करें — एक स्रोत ट्री, एक स्पेक निर्देशिका, एक एकल कैप्चर फ़ाइल — और जो दृश्य आपके पास नहीं हैं, वे रिपोर्ट को भरने के बजाय अपने नियम बंद कर देते हैं।
alibi · 1 source · 377 endpoints
code 372 doc 235
230 corroborated -- vouched for by more than one view
19 endpoints nearly matched another view -- these may be matching failures, not real gaps
SHADOW Shadow API -- Implemented, but no contract describes it
134 findings · 4 critical, 57 high, 62 medium, 11 low
critical POST /api/upload-groups router.go:87
upload paths carry more consequence than reads
critical POST /api/upload-permissions router.go:208
...
... and 122 more (SHADOW in full: -f json)
TWO SURFACES?
The doc view is 97% under /api, and 37 of these findings are outside it.
If that is a separate surface the contract never covered, narrow the scan:
alibi scan <paths> --ignore '^/(?!api(/|$))'
If it is the same surface left undocumented, they are the findings that matter most.
समूह बारह पर रुक जाते हैं — क्रम सबसे खराब पहले है, इसलिए अंतिम भाग सबसे कम जानकारीपूर्ण होता है, और -f json में वह सब मौजूद होता है।
noir के लिए फ़्लैग एक खाली -- के बाद या --noir-arg के माध्यम से दिए जाते हैं। --exclude-path जैसे फ़िल्टर ठीक हैं; वे फ़्लैग जो JSON कॉन्ट्रैक्ट को बदल देंगे या alibi के प्रति-व्यू स्कैन को बाधित कर देंगे (--format, --diff-*, --only-techs, …) उन्हें exit status 2 के साथ अस्वीकार कर दिया जाता है।
- run: alibi scan . ./contracts -f sarif > alibi.sarif
- uses: github/codeql-action/upload-sarif@v3
with: { sarif_file: alibi.sarif }
रिपोर्ट कहती है कि व्यू असहमत हैं; --endpoints बताता है कि उनमें से प्रत्येक में
क्या था।
$ alibi scan ./repo -f json --endpoints
हर व्यू को एक सूची मिलती है: कुंजी, किन व्यूज़ ने इसके लिए वाउच किया, इसके पीछे की तकनीकें, फ़ाइलें, और सामान्यीकरण से पहले की वर्तनी — जहाँ अंतर हमेशा वहीं होता है जब दो पंक्तियों का मेल होना चाहिए था और नहीं हुआ। यह शेष पेलोड का तीन से चार गुना है, इसलिए यह डिफ़ॉल्ट के बजाय एक फ़्लैग है।
या सीधे गेट करें: alibi scan . ./contracts --fail-on high गैर-शून्य के साथ बाहर निकलता है जब कोई फ़ाइंडिंग उस गंभीरता तक पहुँचती है। एक स्कैन जिसे noir पूरी तरह पढ़ नहीं सका, executionSuccessful: false रिपोर्ट करता है, इसलिए एक अपक्षयित रन एक स्वच्छ रन के रूप में पास नहीं होता। एक सिमलिंक, बाइनरी या इमेज जिसे noir ने जानबूझकर छोड़ दिया, गिना नहीं जाता।
Noir एक सामान्य सिंटैक्स का आविष्कार करने के बजाय प्रत्येक फ़्रेमवर्क के अपने रूट सिंटैक्स को बनाए रखता है, इसलिए एक ही एंडपॉइंट कई तरह से लिखा हुआ आता है:
python_flask /api/users/<int:user_id>
aiohttp /users/{id}
java_spring /api/catalog/{id}
oas3 /v1/pets/{petId}
rails /posts/:id
nginx /admin/.*
इन्हें तुलनीय बनाने वाला नियम: किसी path parameter का नाम उसकी पहचान का हिस्सा नहीं होता। {petId} और <int:user_id> एक ही स्लॉट का वर्णन करते हैं; केवल उसकी स्थिति और यह कि वह किसी / को कवर करता है या नहीं, मायने रखता है। नाम साक्ष्य के रूप में रखे जाते हैं और रिपोर्ट किए जाते हैं, लेकिन कभी key तक नहीं पहुँचते।
Findings बताती हैं कि मिलान कैसे हुआ:
| ग्रेड | अर्थ |
|---|---|
G1 | वर्तनी पहले से ही मेल खाती थी |
G2 | parameter सिंटैक्स सामान्यीकृत होने पर वे मेल खाते हैं |
G0 | केवल एक view में यह मौजूद है — कुछ भी मिलान नहीं हुआ |
इस तरह का tool अपने पहले ही रन में सैकड़ों findings रिपोर्ट करके, या ऐसी प्रगति रिपोर्ट करके जो किसी ने की ही नहीं, मर जाता है। छह चीज़ें इसे रोकती हैं:
दोनों views के बिना नियम नहीं चलते। किसी codebase को स्कैन करें जहाँ कहीं भी कोई contract नहीं है, और हर endpoint तकनीकी रूप से एक अवर्णित shadow API के रूप में योग्य हो जाता है। ऐसी findings कुछ नहीं बतातीं सिवाय इसके कि आपने कोई documentation नहीं दी, इसलिए कोई नियम तभी चलता है जब वह जिन-जिन views पर तर्क करता है, वे सभी वास्तव में स्कैन में मौजूद थे। रिपोर्ट उन नियमों के नाम बताती है जो बाहर बैठे रहे।
Near misses को findings के रूप में नहीं, संदेह के रूप में रिपोर्ट किया जाता है। "कोड में है, docs में नहीं" और "दोनों में है, लेकिन alibi उन्हें मिला नहीं सका" में अंतर नहीं किया जा सकता। इसलिए जो endpoint एक view में आता है, उसे near miss के लिए अन्य views के विरुद्ध जाँचा जाता है — वही path भिन्न verb के साथ, या एक segment का अंतर जहाँ एक तरफ parameter है और दूसरी तरफ literal। near miss वाली findings को demote किया जाता है और समीक्षा के लिए flag किया जाता है। वह गिनती totals के बगल में बैठती है, क्योंकि हर finding उतनी ही भरोसेमंद होती है जितनी वह छोटी होती है।