La skill security-audit di Cloudflare: audit di sicurezza AI adversariali con Claude Code (set 2026)
- Spiegare perché 'chiedi a Claude di trovare le vulnerabilità' produce spazzatura sicura di sé, e cosa risolve la separazione dei poteri tra hunter e verifier
- Percorrere le sei fasi e nominare l'artefatto che ciascuna produce, da architecture.md a NEEDS-VALIDATION.md
- Leggere correttamente un findings.json: cosa richiedono confirmed, needs_validation e rejected, e perché solo i record confirmed ricevono una severity
- Eseguire la skill in Claude Code dentro una sandbox che rispetti le sue regole, validare gli output meccanicamente e rieseguire per la copertura
- Metterla a budget: com'è il conto dei token, la regola che fa rifiutare alla skill di lanciare hunter, e i tre modi per tenere una run sostenibile
A metà settembre 2026 Cloudflare ha reso open source una singola skill ed è diventata il repo a crescita più rapida su GitHub: cloudflare/security-audit-skill era a 18,5k stelle il 21 settembre dopo averne aggiunte 2,4k in un solo giorno, e aveva già generato un thread su Hacker News da 211 punti il 17 settembre. Il motivo per cui conta non è il numero di stelle. È che questa skill è il seme del vulnerability harness a livello di flotta che Cloudflare ha descritto a giugno, quello che ha girato su 128 repository e prodotto 7.245 finding azionabili. La skill pubblica è la versione single-repo che puoi eseguire oggi con Claude Code.
Vale la pena essere precisi su cosa sia. Non c'è un binario, non c'è un motore di regole, non c'è un modello proprio. È un SKILL.md più quattordici guide di hunting e due validatori Node a zero dipendenze. Tutto quello che fa, lo fa facendo generare al tuo agente sub-agent isolati con brief ristretti e rifiutando di accettare il loro output finché un agente diverso non ha provato a smontarlo.
Perché "trova le vulnerabilità" da solo non funziona
Il post di Cloudflare di giugno contiene la frase che spiega l'intero design: un agente senza vincoli "modificherà il codice sorgente perché il suo exploit funzioni, e poi riporterà trionfante il bug che ha appena creato". E la regola compagna: "Se a un Hunter è permesso correggere i propri compiti, validerà con sicurezza tutto quello che produce".
È la modalità di fallimento di ogni prompt one-shot "fai l'audit del mio repo". Il modello che ha speso 80k token per formare una teoria è l'ultimo modello che vuoi a giudicare quella teoria. La risposta della skill è strutturale:
- Gli hunter non possono registrare finding. Restituiscono candidati e hanno il divieto di modificare il sorgente target, le note di architettura, il ledger o il file dei finding.
- I verifier non possono cacciare. Un verifier nuovo riceve un candidato, i fatti di architettura e lo schema, e nient'altro, nemmeno la conclusione di un altro verifier. Il suo compito è confutare.
- Niente viene conservato se non lo accetta del codice deterministico. L'agente parent scrive i file condivisi;
validate-findings.cjsevalidate-coverage-ledger.cjsrifiutano tutto ciò che rompe lo schema.
La versione interna di Cloudflare va oltre e usa un modello diverso per la validazione rispetto alla discovery, sulla teoria che pesi separati diano una seconda opinione non condizionata. La skill pubblica non lo impone, ma niente ti impedisce di instradare i sub-agent verifier verso un modello diverso.
Le sei fasi e cosa lascia dietro di sé ciascuna
| Fase | Chi la esegue | Output |
|---|---|---|
| 1. Ricognizione | 4 agenti di ricerca paralleli (stack e build; principal e auth; superfici d'ingresso e sink; cosa è testabile offline) che restituiscono solo fatti | architecture.md (circa 1.000 parole) e un coverage-ledger.json pre-popolato |
| 2. Hunting guidato dalla copertura | Ondate di hunter isolati, una o più unit del ledger ciascuno; un coverage critic dopo ogni ondata | Candidati con proposed_verdict, disposizioni delle unit, note di hardening, gap scoperti di recente |
| 3. Validazione dei candidati | Un verifier nuovo per ogni fingerprint di candidato unico | Una decisione per candidato: confirmed, needs_validation o rejected |
| 4. Output strutturato | Solo il parent | findings.json, ordinato per fingerprint, validato contro lo schema |
| 5. Verifica indipendente dei record | Un verifier nuovo per ogni record confirmed o needs_validation | verified o replace; ogni sostituzione sostanziale riceve un secondo verifier nuovo |
| 6. Reporting neutrale rispetto al target | Il parent, dopo che la fase 5 è passata | REPORT.md, FINDINGS-DETAIL.md (solo da medium in su), NEEDS-VALIDATION.md |
Tutto finisce sotto ~/security-audit-skill/<repo-name>/run-<N>/, con directory per agente agents/<id>/scratch/ e agents/<id>/artifacts/. Solo il parent scrive i file condivisi.
Il coverage ledger è il meccanismo che la maggior parte delle persone si perde. Una unit è una combinazione rilevante di superficie d'ingresso, trust boundary, sottosistema e classe di attacco, con percorsi di partenza nel repo. Le unit passano per planned, in_progress, blocked, covered o candidate, e ogni stato ha regole su quali campi di evidenza vanno compilati. Un coverage critic legge l'intero ledger dopo un'ondata e cerca entry point non mappati, percorsi paralleli non controllati ed esclusioni non giustificate; può riaprire una unit (archiviando il tentativo precedente) ma non può mai proporre un finding. È questo che rende le ri-esecuzioni additive: una seconda run riprende le unit che la prima ha lasciato blocked o riaperte, invece di rifare l'audit di tutto.
I tre verdetti, e perché solo uno porta una severity
Lo schema è rigido su quali campi può usare ciascun verdetto, e il validatore lo fa rispettare.
| Verdetto | Significa | Deve avere | Non deve avere |
|---|---|---|---|
confirmed | Riprodotto in modo indipendente nella sandbox a partire dal sorgente, solo l'effetto minimo osservato | root_cause, intended_behavior, trace (da entrypoint a sink), evidence, conditions, execution, remediation, severity, confidence | claimed_root_cause, blockers, validation_plan, reason |
needs_validation | Fondato sul sorgente, ma bloccato da un fatto preciso che non si può risolvere in locale (un'impostazione di deployment, una config accessibile solo al proprietario) | claimed_root_cause, trace, evidence, blockers, validation_plan | severity, execution, remediation |
rejected | Il verifier lo ha confutato | claimed_root_cause, trace, evidence, reason | severity, execution, remediation, blockers |
Ne seguono tre conseguenze:
- Un finding
needs_validationnon ha severity per design. Non è un "medium"; è una domanda per il proprietario del codice con un piano preciso per rispondere.NEEDS-VALIDATION.mdesiste perché quella lista non venga scambiata per una lista di vulnerabilità. - La severity richiede un impatto dimostrato, non una voce mancante in una checklist. La calibrazione in
SKILL.md: critical è esecuzione di codice non autenticata, accesso completo ai dati o account takeover; high è la sconfitta completa di un controllo esplicito (bypass dell'auth, accesso cross-tenant); medium è blast radius limitato o precondizioni non comuni; low è divulgazione di dati non segreti; informational è un'osservazione confermata con impatto minimo. "Best practice mancante" esplicitamente non è un finding. - Una run pulita riporta zero. La guida al reporting dice che un report proporzionato può non avere finding confermati e deve dirlo chiaramente. Se la tua run "trova" venti critical in un servizio piccolo, sospetta del setup della sandbox prima di sospettare del servizio.
Per chi legge questa sezione, la guida di hunting AI/LLM è la parte più affilata. La sua regola d'apertura: "La prompt injection da sola non è un finding. Richiedi un boundary failure a livello di codice." Un hunter deve mostrare l'attaccante, il principal colpito, l'identità di esecuzione e un'azione o divulgazione non autorizzata, con una traccia nel sorgente dall'input controllato dall'attaccante fino all'effetto collaterale. I pattern verso cui manda gli hunter sono quelli delle nostre pagine su prompt injection e MCP tool poisoning, ma inquadrati come difetti del codice: argomenti di tool che arrivano a SQL o a una shell senza validazione lato handler, sub-agent che ereditano credenziali complete invece della minima autorità, descrizioni di tool trattate come autorizzazione, output del modello renderizzato in HTML o in un comando senza encoding, context bleed cross-tenant da chiavi di cache troppo ampie. Convincere il modello a dire qualcosa di sgarbato non conta.
La regola della sandbox non è un consiglio
SKILL.md richiede che qualsiasi codice controllato dal target (test, fixture, la build stessa del progetto) giri dentro una sandbox imposta dal sistema operativo senza rete esterna, al massimo con un namespace di loopback isolato, sorgente target in sola lettura, scritture confinate a scratch/ e limiti rigidi su CPU, memoria, processi e dimensione dei file. Ai verifier viene detto che, se la sandbox non è disponibile, il candidato resta semplicemente non validato. La promozione da scratch/ agli artifacts/ conservati rifiuta symlink, file con link multipli, archivi e copie ricorsive, e non riapre nulla per path.
È lo stesso threat model della nostra pagina sui coding agent sotto attacco, rivolto verso l'interno: il repository di cui stai facendo l'audit potrebbe essere ostile, e la sua test suite è codice che stai per eseguire. In Claude Code, significa eseguire l'audit con i controlli di sandbox e credential masking attivi, non nella tua shell quotidiana con le tue variabili d'ambiente reali. Una trappola dell'harness di Cloudflare stesso si applica se annidi Docker dentro un container: servono seccomp=unconfined e apparmor=unconfined "altrimenti fallisce silenziosamente".
- npx skills add https://github.com/cloudflare/security-audit-skill --skill security-audit. La CLI skills (vercel-labs/skills) la mette in .claude/skills/ per Claude Code o in .agents/skills/ per Codex, Cursor e Gemini CLI; aggiungi -g per un'installazione globale, -a claude-code per puntare a un solo agente. Leggi SKILL.md prima di eseguirla: è il contratto che stai per eseguire.
- Avvia Claude Code nel repo target con sandboxing e credential masking attivi, nessuna credenziale di produzione nell'ambiente e uscita di rete limitata al tuo provider di modelli. La skill ha bisogno di un agente che possa generare sub-agent paralleli; l'Agent tool di Claude Code è idoneo.
- Scrivi 'security audit this codebase' o 'find security vulnerabilities in ./src'. Una domanda più ristretta ('is this JWT check safe?') attiva invece la guidance mode, che risponde senza creare una directory di run. Per una prima run, puntala su una sola directory delimitata, non sulla root del monorepo.
- Tutto compare sotto ~/security-audit-skill/<repo>/run-1/. architecture.md dovrebbe esistere entro pochi minuti; coverage-ledger.json cresce unit dopo unit; findings.json compare solo dopo la fase 4. Se dopo la ricognizione non è arrivato nulla, controlla che l'agente abbia una sandbox in cui può eseguire.
- node <skill-dir>/validate-findings.cjs run-1/findings.json e node <skill-dir>/validate-coverage-ledger.cjs run-1/coverage-ledger.json. La skill li esegue da sola, ma eseguirli tu stesso è il modo più economico per accorgerti di una run interrotta da un limite di sessione.
- Rispondi a ogni blocker (è formulato come una domanda sul tuo deployment) e promuovi o scarta il record. Poi esegui di nuovo: i campi prior_status del ledger fanno sì che la seconda run punti alle unit blocked e riaperte invece di ricominciare da capo. I dati di Cloudflare stessa dicono che una singola run trova circa la metà di quello che trovano run ripetute.
Frasi di attivazione e i comandi dei validatori
# Full audit (creates ~/security-audit-skill/<repo>/run-N/) security audit this codebase find security vulnerabilities in ./src # Guidance mode (no run directory, no sub-agent fleet) is the session cookie handling in auth/session.ts safe against fixation? # After a run: mechanical checks, zero dependencies beyond Node node .claude/skills/security-audit/validate-findings.cjs ~/security-audit-skill/<repo>/run-1/findings.json node .claude/skills/security-audit/validate-coverage-ledger.cjs ~/security-audit-skill/<repo>/run-1/coverage-ledger.json # What the schema hard-limits (validator rejects beyond these) # findings.json: 5 MiB, 1,000 findings, 64 nesting levels # coverage-ledger.json: 5 MiB, 10,000 units, 1,000 entries per collection
Quanto costa, e come tenerlo sostenibile
Il thread su HN parla soprattutto del conto. Un utente ha riportato "ho buttato 1M di token per niente in una codebase media"; un altro ha messo il tetto pratico a 150k token, "dove inizi a entrare nella dumb zone" dell'attenzione degradata. Sono aneddoti, non misurazioni, ma combaciano con la forma del design: quattro agenti di ricognizione, un'ondata di hunter, un verifier per candidato, un critic per ondata, poi un secondo verifier per ogni record sopravvissuto. I numeri della flotta di Cloudflare danno la scala onesta: un repository standard da 30k righe ha richiesto da 3 a 4 ore per circa 100 finding grezzi, e su tutta la flotta il 58% dei candidati grezzi è sopravvissuto alla validazione (12.057 su 20.799).
Tre cose nella skill stessa le impediscono di sfuggire di mano:
- La regola della riserva di budget. Prima di ogni ondata il parent deve riservare budget per gli hunter, il passaggio di validazione, il critic post-ondata e un critic finale pulito.
HUNTING.mddice: se quelle riserve obbligatorie non ci stanno, non lanciare nessun hunter da quell'ondata, e segna le unit come deferred con la motivazione di budget. Una run che finisce con unit deferred è una run che ha rispettato il tuo budget, non una run rotta. - Brief ristretti. Ogni sub-agent riceve una unit o un candidato. L'harness di Cloudflare ha tenuto ogni agente sotto il 25% della sua context window e attribuisce a questo, più che a qualsiasi formulazione del prompt, la qualità dei finding.
- Guidance mode. La maggior parte delle domande di sicurezza non ha bisogno della pipeline. Falle direttamente e la skill risponde senza generare nulla.
Dalla tua parte: limita la prima run a una sola directory; usa un modello con contesto ampio e letture di cache economiche per gli hunter e uno più forte per i verifier; metti un task budget sulla sessione; e tratta una run interrotta da un limite di sessione come parziale, non fallita, perché il ledger registra esattamente dove si è fermata.
Dove si colloca rispetto a Semgrep, CodeQL e alla code review AI
Non è un sostituto dell'analisi statica e non prova a esserlo. Il post di Cloudflare ha un dettaglio rivelatore: hanno collegato Semgrep all'harness e gli agenti "lo hanno ignorato completamente", preferendo leggere ed eseguire il codice. Gli strumenti statici ti danno una copertura deterministica, economica e ripetibile di pattern noti; questa skill ti dà una copertura costosa, probabilistica e pesante di ragionamento sui boundary failure che i pattern matcher non riescono a esprimere, con un passaggio di validazione che gli strumenti statici non hanno. Usa entrambi. E non confonderla con la review al momento della PR: open-code-review di Alibaba è un reviewer di diff che gira in secondi per pull request; questo è un audit di più ore su una codebase a riposo.
Mettiti alla prova
0/6Fonti e approfondimenti
- cloudflare/security-audit-skill su GitHub — README,
SKILL.md, le guide di fase (RECONNAISSANCE.md,HUNTING.md,VALIDATION-AND-REPORTING.md), le quattordici guide per classe di attacco tra cuiAI-AND-LLM.md,report-schema.jsone i due validatori; MIT - Build your own vulnerability harness — blog di Cloudflare, 18 giugno 2026 (Grant Bourzikas): come la skill è cresciuta fino all'harness di flotta, il funnel da 20.799 a 12.057 a 7.245, il dato delle 3–4 ore per repo da 30k righe, la regola del "correggere i propri compiti", le trappole del Docker annidato e del 200 OK con errore
- Discussione su Hacker News (item 49736466) — report di token in prima persona e le obiezioni sui costi
- vercel-labs/skills — la CLI
npx skills adde dove installa le skill per ciascun agente - Lo standard aperto Agent Skills — perché un solo
SKILL.mdgira in Claude Code, Codex, Cursor e Gemini CLI
Prossimi passi
- Verificare le skill per agenti che installi — questa skill genera agenti che eseguono il codice del tuo repo; leggila prima di fidarti di qualsiasi skill, compresa questa
- Hardening delle run autonome — il setup di sandbox, segreti ed egress di cui ha bisogno un audit non presidiato di più ore
- Open Code Review: il reviewer AI ibrido di Alibaba — la controparte al momento della PR, e la stessa lezione precision-versus-recall