
कोड कैनरीज़ (Code canaries) जो भ्रमपूर्ण ('स्लॉप') कमजोरी रिपोर्टों को त्वरित रूप से छाँटने में मदद करते हैं।
honeyslop, ओपन-सोर्स परियोजनाओं के लिए कोड कैनरीज़ (डिकॉय) है जो AI-भ्रमित ("स्लॉप") और असत्यापित भेद्यता रिपोर्टों में डूबी हुई हैं। ऐसे प्रतिकूल शोर इंजेक्शन के साथ, एक स्लॉप स्कैनर कैनरी को ग्रहण करता है, फिर उसके आधार पर एक भेद्यता "रिपोर्ट" उत्पन्न करता है। रिपोर्ट स्वयं को स्लॉप के रूप में पहचानती है। इसे एक grep में बंद करें।
यह एक त्वरित PoC है, जो एक मज़ाक के रूप में वाइब-कोडेड है (उत्पादन-ग्रेड नहीं), क्योंकि हमें स्वयं raptor पर एक स्लॉप रिपोर्ट मिली थी, जो Claude Code पर आधारित एक स्वायत्त आक्रमण/रक्षा एजेंट है। मज़ा आना चाहिए!
कोड कैनरीज़ परिचित वर्गीकरण संकेतों (जैसे टेस्ट फ़ाइलों में पहचान, उदाहरण रहस्य, अस्तित्वहीन पथ) को जानबूझकर चिह्नकों या डिकॉय में विस्तारित करते हैं। परीक्षणों में, ये कैनरीज़ स्लॉप को चिह्नित करने के लिए पर्याप्त काम करते हैं, लेकिन इन्हें और बेहतर बनाया जा सकता है (वास्तविक कोड में एम्बेडेड, कम संकेतक फ़ंक्शन/फ़ाइल/निर्देशिका नाम, नियमित रूप से नए कोड के रूप में पुनर्जीवित, आदि)।
लेखक: गादी एवरॉन (@gadievron), जॉन कार्टराईट (@grokjc), डैनियल कथबर्ट (@danielcuthbert), और मिचल कामेंस्की (@kamenskymic, परियोजना के नामकरण के लिए श्रेय)।
अपने जोखिम पर उपयोग करें। यदि आप इसे उत्पादन में चिपकाते हैं, तो यह आपकी समस्या है। नीचे अस्वीकरण देखें।
प्रत्येक आने वाली रिपोर्ट के लिए, क्रम में:
zqx_tarnish_v3, zqxTarnishV3, _validate_pep_440_plus; साथ ही handle_*_request यदि आपने F+G को निजी रूप से अपनाया है) को grep करें → बंद करें। (Rust Python के समान zqx_tarnish_v3 snake_case नाम का उपयोग करता है। Go zqxTarnishV3 का उपयोग करता है, जो JS नाम से मेल खाता है।)CVE-2025-99919 (नकली) को grep करें → बंद करें।कैनरी के दो श्रेणियाँ:
| चरण | फ़ाइल(एँ) | स्वरूप |
|---|---|---|
| A | python/legacy_utils.py, python/session_restore.py, python/compat_tokens.py, js/legacy_utils.js, rust/legacy_utils.rs, rust/session_restore.rs, go/legacy_utils.go, go/session_restore.go | ~15 CWE सिंक + नकली रहस्य + शिब्बोलेथ्स |
| B | c/buffer_ops.c, rust/buffer_ops.rs, go/buffer_ops.go | 4 memcpy/memmove स्वरूप (CWE-120/121/787/170) |
| C | A में विलय | विस्तारित CWE उपज |
| D | c/heartbeat.c + c/sat.h, c/tls_heartbeat.c, rust/heartbeat.rs, rust/tls_heartbeat.rs, go/heartbeat.go, go/tls_heartbeat.go | हार्टब्लीड सिल्हूट |
| E | python/regex_validator.py, js/regex_validator.js, rust/regex_validator.rs, go/regex_validator.go | विनाशकारी-बैकट्रैक regex + नकली CVE-2025-99919 |
| F+G | private/fractal_dag/ (इस रिपॉजिटरी में नहीं) | handle_*_request प्रविष्टियों के 12-नोड DAG में चरण-A सिंक |
देखें सुरक्षा मॉडल कि प्रत्येक चरण कमजोर दिखने के बावजूद निष्क्रिय कैसे रहता है।
कैनरी कोड फ़ाइलें जानबूझकर प्रशंसनीय अप्रचलित मॉड्यूल की तरह पढ़ी जाती हैं — टिप्पणियों या पहचानकर्ताओं में कोई "कैनरी", "हनीपॉट" या "ट्रिपवायर" भाषा नहीं। यह फ़ाइलों को स्कैनरों से स्वयं-पहचानने से रोकता है, लेकिन इसका मतलब यह भी है कि ये फ़ाइलें सुरक्षित क्यों हैं का दस्तावेज़ीकरण यहाँ रहता है, प्रत्येक फ़ाइल के डॉकस्ट्रिंग में नहीं। कैनरी की समीक्षा या रोटेट करते समय, जाँचें कि नीचे प्रत्येक परत अभी भी अक्षुण्ण है।
ये फ़ाइलें कमजोर-आकार का कोड हैं — और कुछ (जैसे python/session_restore.py का pickle.loads, c/tls_heartbeat.c का असीमित memcpy) पहुँच योग्य होने पर वास्तविक रूप से शोषणीय होंगी। यही डिज़ाइन है। स्कैनरों का सिंक को चिह्नित करना पूरा बिंदु है; नीचे की परतें निष्पादन को अवरुद्ध करती हैं, स्कैनर संकेत को नहीं। पैटर्न-आधारित स्कैनर (grep, semgrep, LLM-आधारित स्लॉप पाइपलाइन — प्राथमिक खतरा मॉडल) स्रोत को पाठ के रूप में पढ़ते हैं और रनटाइम पहुँच की परवाह किए बिना निष्कर्ष प्रकट करते हैं। बिल्ड-एकीकृत C स्कैनर (CodeQL डिफ़ॉल्ट, clang-static-analyzer) केवल संकलित फ़ाइलें देखते हैं, इसलिए असंकलित C कैनरी उनके लिए अदृश्य हैं — एक स्वीकृत समझौता, क्योंकि स्लॉप जनरेटर बड़े पैमाने पर बिल्ड के बजाय स्रोत पढ़ते हैं।
पाँच स्वतंत्र परतें इन फ़ाइलों को निष्क्रिय रखती हैं:
raise ImportError / throw new Error — एक सादा import / require किसी भी परिभाषा को बाँधने से पहले ही समाप्त हो जाता है।if False: / if (false) के अंतर्गत प्रत्येक def/function — परत 1 को बायपास करने पर भी नाम कभी रनटाइम नेमस्पेस में प्रवेश नहीं करते।__all__: list[str] = [] (स्टार-आयात कुछ भी निर्यात नहीं करता)। JS: module.exports = {} (CommonJS उपभोक्ताओं को एक खाली ऑब्जेक्ट मिलता है)।zqx_tarnish_v3, zqxTarnishV3, _validate_pep_440_plus)। इनमें से किसी एक को उद्धृत करने वाली कोई भी रिपोर्ट स्वयं को स्लॉप के रूप में पहचानती है।SECURITY.md.template और कैसे प्रयास करें)।चरण E छठी परत जोड़ता है: विनाशकारी-बैकट्रैक regex केवल एक स्ट्रिंग लिटरल के रूप में संग्रहीत है, मॉड्यूल स्कोप पर re.compile / new RegExp को पारित नहीं किया गया। एक हार्नेस जो परत 1 को हटाता है, वह भी संकलित बैकट्रैकिंग इंजन को ट्रिगर नहीं कर सकता।
स्कैनर AST को raise / throw से आगे और मृत ब्लॉक में चलते हैं, इसलिए सिंक अभी भी निष्कर्ष के रूप में प्रकट होते हैं — यह अभीष्ट व्यवहार है।
buffer_ops.c)सुरक्षा संरचनात्मक है — प्रत्येक आकार के साथ एक प्रमाण है:
bufops_copy_banner — src एक स्ट्रिंग लिटरल है, n = sizeof(literal), _Static_assert इसे गंतव्य आकार पर पिन करता है।bufops_copy_bounded — if (n > dst_cap) n = dst_cap; memcpy से ठीक पहले की लाइन CWE-787 दावे को असंभव बनाती है। C17 memcpy(dst, NULL, 0) UB से बचने के लिए n == 0 पर शॉर्ट-सर्किट।bufops_copy_truncating — n <= dst_cap - 1, dst[n] अधिकतम dst_cap - 1 पर पहुँचता है; dst_cap == 0 पर प्रारंभिक रिटर्न।bufops_shift — i + n और j + n दोनों cap पर बाध्य; memmove स्पष्ट रूप से ओवरलैप का समर्थन करता है।अतिरिक्त अलगाव: सभी फ़ंक्शन static हैं (कोई बाहरी लिंकेज नहीं) और फ़ाइल किसी भी बिल्ड लक्ष्य में नहीं जोड़ी गई है।
heartbeat.c + sat.h)हार्टब्लीड सिल्हूट (uint16_t payload_len → malloc(1+2+payload_len+16) → memcpy) स्तरित गार्डों द्वारा निष्क्रिय किया गया है: