
محلل ثابت بدون تبعيات لأخطاء سلامة دوائر zk في تطبيقات o1js/Mina zkApps ودوائر Noir
حزمة مجتمعية:
o1js-scanمُدرجة في دليل حزم o1js المجتمعية الرسمي.
الأحدث: 0.22.0 — خادم MCP محلي يتيح لـ Claude Code وCursor وغيرهما من مساعدي البرمجة بالذكاء الاصطناعي تشغيل الماسح أثناء كتابتك لتطبيق zkApp:
pip install 'o1js-scan[mcp]'. يعمل على جهازك عبر stdio ولا يرفع أي شيء. الفحص الذي لم يحلل أي ملفات يُعد خطأً، وليس نتيجة نظيفة، والنتيجة التي لا تحتوي على أي اكتشافات تنص على أنها ليست ضمانًا أمنيًا. لا يزال الماسح الأساسي بلا أي تبعيات. راجع سجل التغييرات.
محلل ثابت سريع وبلا تبعيات لأخطاء سلامة دوائر zk في:
.ts / .js) — دوائر Kimchi من أجسام @method.nr) — لغة ZK DSL الشبيهة بـ Rust من Aztec (بما في ذلك الأنماط على شكل aztec-nr)عادةً لا تكون الأخطاء الحرجة أمنيًا في نظام الإثبات — بل في
قيود التطبيق نفسه: الشهود الذين يتحكم بهم المُثبِت لكن الدائرة لا
تربطهم أبدًا. o1js-scan هو ماسح الإشارات غير المُقيَّدة لأبناء عمومة Circom
في منظومتي Mina وNoir.
راجع أيضًا: gnark-safety (دوائر gnark)، vk-guard (انحدار مفتاح التحقق).
pip install o1js-scan
# or: pipx install o1js-scan
# or: npm install -D o1js-scan
o1js-scan path/to/zkapp # o1js + Noir (auto)
noir-scan path/to/circuits # same binary — Noir-friendly alias
noir-scan . --lang noir --fail-on high --sarif noir.sarif
بالنظر إلى خزنة يكون فيها مبلغ withdraw شاهدًا يتحكم فيه المُثبِت ولا
يُربط أبدًا بحالة السلسلة:
$ o1js-scan examples/vulnerable_vault.ts --include-examples
LOW O1JS_UNCONSTRAINED_RECIPIENT vulnerable_vault.ts:23 fn=withdraw Recipient `to` is prover-chosen in `withdraw`
HIGH O1JS_UNCONSTRAINED_WITNESS vulnerable_vault.ts:23 fn=withdraw Unconstrained witness `amount` flows to send_amount in `withdraw`
o1js-scan: 2 finding(s) [1 high, 1 low] in 1 of 1 file(s) — fails (--fail-on high)
$ echo $?
1
--include-examples مطلوب هنا فقط لأن ملف العرض التوضيحي يقع تحت
examples/، وهو ما يصنّفه مصنّف المسار على أنه أقل خطورة افتراضيًا حتى لا
يتسبب كود العينة الخاص بالمستودع في فشل البناء. نفس العقد في src/ يُبلّغ
عن HIGH بدون أي علامة.
اكتشاف HIGH هو الثغرة القابلة للسحب. العقد المُصلَّح
(examples/safe_vault.ts) يُسقطه ويخرج بـ 0، محتفظًا فقط بالمعلوماتي
LOW على المستلم الذي يختاره المُثبِت:
$ o1js-scan examples/safe_vault.ts --include-examples
LOW O1JS_UNCONSTRAINED_RECIPIENT safe_vault.ts:23 fn=withdraw Recipient `to` is prover-chosen in `withdraw`
o1js-scan: 1 finding(s) [1 low] in 1 of 1 file(s) — passes (--fail-on high)
$ echo $?
0
راجع examples/ للحصول على أزواج o1js وNoir القابلة للاستغلال/المصححة.
pip install o1js-scan
لتثبيت CLI عالمي معزول، استخدم pipx:
pipx install o1js-scan
بالنسبة لمستودعات تطبيقات Noir أو Aztec أو o1js القائمة على Node/npm، قم بتثبيت غلاف npm:
npm install -D o1js-scan
npx noir-scan . --lang noir --fail-on high
حزمة npm هي غلاف رفيع حول نفس محلل Python وتتطلب
Python 3.8+ على PATH (python3 أو python). اضبط O1JS_SCAN_PYTHON لاختيار
مفسر محدد.
أو من المصدر:
git clone https://github.com/auditinfra-io/o1js-scan
cd o1js-scan
pip install -e .
لا توجد تبعيات Python من طرف ثالث. Python 3.8+. يتم تثبيت سكربت الطرفية noir-scan
إلى جانب o1js-scan (نقطة الدخول نفسها)، بما في ذلك عبر غلاف npm.
# scan a directory (recursively; skips node_modules, target/, .git, …)
o1js-scan path/to/project
# Noir-only / o1js-only
noir-scan circuits --lang noir
o1js-scan src --lang o1js
# scan a single file
o1js-scan src/MyContract.ts
noir-scan src/main.nr
# machine-readable output for CI
o1js-scan src --json
# SARIF 2.1.0 for GitHub code scanning (writes o1js-scan.sarif by default)
o1js-scan src --sarif
noir-scan . --lang noir --sarif noir.sarif
# choose which severity fails CI (critical|high|medium|low|none; default high)
o1js-scan src --fail-on medium
# progressive/power-user gate (equivalent to --fail-on medium)
o1js-scan src --strict
# test code is excluded by default (both backends); opt back in
o1js-scan src --include-tests
# example code is downgraded to LOW by default; keep original severity
o1js-scan src --include-examples
# a path with no o1js / Noir source exits 2; opt out where that is expected
o1js-scan packages/ --allow-empty
o1js-scan --version
يُعاد رمز الخروج 1 عند وجود نتيجة عند مستوى --fail-on أو أعلى منه (الافتراضي high) و0 بخلاف ذلك — لذا يمكنك إدراجه مباشرة في CI. مع الإعداد الافتراضي، لا تؤدي نتيجة منخفضة/متوسطة (بما في ذلك قاعدة المستلم المعلوماتية أدناه) إلى إفشال البناء؛ استخدم --fail-on none للإبلاغ فقط، أو --strict (اختصار لـ --fail-on medium) لبوابة أكثر صرامة مع الاستمرار في التعامل مع النتائج منخفضة الخطورة كاستشارية. الخياران متعارضان فلا يمكن أن يكون إعداد CI غامضًا. مسار فحص مفقود يخرج بـ 2 مع خطأ على stderr، فلا يمكن لخطأ مطبعي أن يمر عبر CI بصمت كتشغيل نظيف. وكذلك الحال بالنسبة لمسار موجود لكنه لا يحتوي على أي مصدر o1js أو Noir يمكن للمحلل قراءته (على سبيل المثال --lang noir موجّه إلى مشروع o1js)؛ مرّر --allow-empty حيث يكون ذلك مشروعًا. كل تشغيل
يطبع ملخصًا من سطر واحد (أعداد حسب الخطورة وحكم البوابة) إلى stderr.
يُستثنى كود الاختبار افتراضيًا — في كلا الخلفيتين. تبني الاختبارات عمدًا قيمًا غير صالحة ومعاملات سيئة لإثبات أن التأكيدات ترفضها، لذا فإن وجود نتيجة هناك هو الغرض من الاختبار وليس خطأ في الدائرة. يُحتسب الملف ككود اختبار عندما:
*.test.ts / *.spec.ts (ومتغيرات .js/.jsx/.tsx/.mjs
/.cjs)، أو *_test.nr / test_*.nr؛test/ أو tests/ أو __tests__/ أو spec/ أو __mocks__/؛#[test] / #[test(...)]، أو تقع داخل كتلة mod test { … } / mod tests { … } —
محددة النطاق بالكتلة، لذا فإن وحدة اختبار في أسفل ملف إنتاجي لا تُسكِت بقية الملف.مرّر --include-tests للإبلاغ عنها.
يُخفَّض كود المثال، لا يُحذف. نتيجة في دليل examples/ أو example/، أو في ملف باسم *.eg.ts (وكذلك .nr وبقية امتدادات JS/TS)، تُخفَّض إلى LOW مع ملاحظة — لا تزال مُبلَّغًا عنها، لكنها لم تعد قادرة على إفشال بناء. كود المثال مبسّط عمدًا، ووسم أمثلة إطار العمل نفسه كالثغرات هو ضجيج؛ لكنه يُنسخ إلى الإنتاج أكثر بكثير مما يُنسخ كود الاختبار، ولهذا يُخفَّض بدلًا من إخفائه. مرّر --include-examples للحفاظ على الخطورة الأصلية.