Passa al contenuto principale

La skill security-audit di Cloudflare: audit di sicurezza AI adversariali con Claude Code (set 2026)

Intermedio
What you'll learn
  • 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.cjs e validate-coverage-ledger.cjs rifiutano 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​

FaseChi la esegueOutput
1. Ricognizione4 agenti di ricerca paralleli (stack e build; principal e auth; superfici d'ingresso e sink; cosa è testabile offline) che restituiscono solo fattiarchitecture.md (circa 1.000 parole) e un coverage-ledger.json pre-popolato
2. Hunting guidato dalla coperturaOndate di hunter isolati, una o più unit del ledger ciascuno; un coverage critic dopo ogni ondataCandidati con proposed_verdict, disposizioni delle unit, note di hardening, gap scoperti di recente
3. Validazione dei candidatiUn verifier nuovo per ogni fingerprint di candidato unicoUna decisione per candidato: confirmed, needs_validation o rejected
4. Output strutturatoSolo il parentfindings.json, ordinato per fingerprint, validato contro lo schema
5. Verifica indipendente dei recordUn verifier nuovo per ogni record confirmed o needs_validationverified o replace; ogni sostituzione sostanziale riceve un secondo verifier nuovo
6. Reporting neutrale rispetto al targetIl parent, dopo che la fase 5 è passataREPORT.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.

VerdettoSignificaDeve avereNon deve avere
confirmedRiprodotto in modo indipendente nella sandbox a partire dal sorgente, solo l'effetto minimo osservatoroot_cause, intended_behavior, trace (da entrypoint a sink), evidence, conditions, execution, remediation, severity, confidenceclaimed_root_cause, blockers, validation_plan, reason
needs_validationFondato 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_planseverity, execution, remediation
rejectedIl verifier lo ha confutatoclaimed_root_cause, trace, evidence, reasonseverity, execution, remediation, blockers

Ne seguono tre conseguenze:

  • Un finding needs_validation non ha severity per design. Non è un "medium"; è una domanda per il proprietario del codice con un piano preciso per rispondere. NEEDS-VALIDATION.md esiste 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".

Guided walkthrough1 of 6
  1. 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.

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:

  1. 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.md dice: 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.
  2. 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.
  3. 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.

Termini che incontrerai nella directory della run
Premi Invio o Spazio per girare la carta. Usa le frecce sinistra e destra per spostarti tra le carte.Termine mostrato.
1 / 8

Mettiti alla prova

0/6
  1. Un hunter è convinto di aver trovato un bypass dell'auth. Cosa gli è permesso farne?
  2. Un record in findings.json ha verdetto needs_validation e severity high. Cosa è successo?
  3. La tua test suite fa chiamate HTTP in uscita. Cosa dice la skill di fare a hunter e verifier?
  4. Un hunter mostra che un'email costruita ad arte fa dire all'assistente qualcosa di offensivo. Secondo AI-AND-LLM.md questo è:
  5. La run finisce con diverse unit segnate come deferred e una motivazione di budget. Cosa significa?
  6. I dati della flotta di Cloudflare dicono che una singola run trova all'incirca quale quota di ciò che trovano run ripetute?

Fonti 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 cui AI-AND-LLM.md, report-schema.json e 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 add e dove installa le skill per ciascun agente
  • Lo standard aperto Agent Skills — perché un solo SKILL.md gira in Claude Code, Codex, Cursor e Gemini CLI

Prossimi passi​