
Analizzatore statico senza dipendenze per bug di solidità dei circuiti zk in o1js/Mina zkApps e circuiti Noir
Pacchetto della community:
o1js-scanè elencato nella directory ufficiale o1js Community Packages.
Ultima versione: 0.22.0 — un server MCP locale consente a Claude Code, Cursor e ad altri assistenti di coding AI di eseguire lo scanner mentre scrivi una zkApp:
pip install 'o1js-scan[mcp]'. Viene eseguito sulla tua macchina tramite stdio e non carica nulla. Una scansione che non ha analizzato alcun file è un errore, non un risultato pulito, e un risultato senza rilevamenti dichiara di non essere una garanzia di sicurezza. Lo scanner principale è ancora privo di dipendenze. Vedi CHANGELOG.
Un analizzatore statico veloce e senza dipendenze per bug di soundness dei circuiti zk in:
.ts / .js) — circuiti Kimchi dai corpi @method.nr) — il DSL ZK in stile Rust di Aztec (inclusi pattern modellati su aztec-nr)I bug critici per la sicurezza di solito non sono nel proving system — sono nei
vincoli dell'applicazione stessa: witness controllati dal prover ma che il circuito
non vincola mai. o1js-scan è lo scanner per segnali under-constrained per i cugini di Circom
negli ecosistemi Mina e Noir.
Vedi anche: gnark-safety (circuiti gnark), vk-guard (regressione della verification-key).
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
Dato un vault il cui importo di withdraw è un witness controllato dal prover che
non è mai vincolato allo stato on-chain:
$ 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 è necessario qui solo perché il file demo si trova sotto
examples/, che il classificatore di percorsi declassa per impostazione predefinita
affinché il codice di esempio di un repository non possa far fallire la sua build. Lo
stesso contratto nel tuo src/ segnala HIGH senza alcun flag.
Il risultato HIGH è il bug svuotabile. Il contratto corretto
(examples/safe_vault.ts) lo elimina ed esce con 0, mantenendo solo il risultato
informativo LOW sul destinatario scelto dal prover:
$ 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
Consulta examples/ per le coppie vulnerabili/corrette di o1js e Noir.
pip install o1js-scan
Per un'installazione CLI globale isolata, usa pipx:
pipx install o1js-scan
Per i repository di app Noir, Aztec o o1js basati su Node/npm, installa il wrapper npm:
npm install -D o1js-scan
npx noir-scan . --lang noir --fail-on high
Il pacchetto npm è un sottile wrapper attorno allo stesso analizzatore Python e richiede
Python 3.8+ nel PATH (python3 o python). Imposta O1JS_SCAN_PYTHON per scegliere un
interprete specifico.
Oppure dai sorgenti:
git clone https://github.com/auditinfra-io/o1js-scan
cd o1js-scan
pip install -e .
Nessuna dipendenza Python di terze parti. Python 3.8+. Lo script console noir-scan è
installato insieme a o1js-scan (stesso entry point), anche tramite il wrapper
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
Il codice di uscita è 1 quando è presente un finding al livello --fail-on o superiore (predefinito high) e 0 altrimenti — così puoi inserirlo direttamente nella CI. Con il valore predefinito, un finding di livello low/medium (inclusa la regola informativa sui destinatari di seguito) non fa fallire la build; usa --fail-on none per limitarti a segnalare, oppure --strict (una scorciatoia per --fail-on medium) per applicare un gate più rigoroso trattando comunque i finding di bassa severità come informativi. Le due opzioni sono mutuamente esclusive, così la configurazione della CI non può essere ambigua. Un percorso di scansione mancante esce con 2 e un errore su stderr, così un refuso non può passare silenziosamente in CI come una scansione pulita. Lo stesso vale per un percorso che esiste ma non contiene alcun sorgente o1js o Noir che l'analizzatore possa leggere (ad esempio --lang noir puntato a un progetto o1js); passa --allow-empty dove ciò è legittimo. Ogni esecuzione
stampa un riepilogo di una riga (conteggi per severità e verdetto del gate) su stderr.
Il codice di test è escluso per impostazione predefinita — per entrambi i backend. I test costruiscono deliberatamente valori non validi e transazioni errate per dimostrare che gli assert le rifiutano, quindi un finding lì è lo scopo del test piuttosto che un bug del circuito. Un file è considerato codice di test quando: