Skip to content

Piano di Ottimizzazione Token per Pentest/Bug Bounty

Scopo

Questo documento serve a far fare a Opus High un double check di un piano di riduzione consumo token che non deve ridurre:

  • copertura della superficie di attacco
  • numero di finding trovati
  • qualità del ragionamento
  • correttezza metodologica
  • qualità di verifica ed evidenze

L'obiettivo non è "fare meno test", ma spendere meno token per lo stesso lavoro utile e smettere di spendere token su lavoro impossibile, duplicato o static prompt tax.

Executive Summary

Le cause principali del burn non sembrano essere singole prompt "troppo lunghe", ma una combinazione di:

  1. Loop bug bounty che continua a spawnare sessioni anche in rate limit
  2. Moltiplicazione del costo base per subagent dovuta a skill monolitiche molto pesanti
  3. Parallelismo alto che amplifica quel costo base
  4. Analisi AI del proxy attiva di default quando ci sono sessioni proxy
  5. Artifact explosion (.prompt-*, .session-prompt-*, log enormi) che non è la causa primaria del billing, ma è un forte indicatore di loop e spawn eccessivi

Evidenze raccolte nel repository

1. Loop perpetuo senza vera gestione del rate limit

File coinvolti:

  • bugbounty/PERPETUAL-HUNTING-LOOP.sh
  • bugbounty/loop-manager.sh
  • .claude/skills/bb-loop/SKILL.md

Osservazioni:

  • bugbounty/PERPETUAL-HUNTING-LOOP.sh lancia 4 hunt paralleli per sessione.
  • Ogni hunt usa:
  • claude -p
  • --max-turns 250
  • timeout di 1 ora
  • A fine sessione il loop dorme solo 10 secondi e riparte.
  • Non c'è una vera pausa globale quando Claude risponde con messaggi tipo You're out of extra usage.

Fatto misurato dai log:

  • Nel file bugbounty/perpetual-hunting-console.log ci sono 391 linee con out of extra usage.
  • Nel file bugbounty/PERPETUAL-HUNTING.log, nell'ultima ora loggata risultano 540 start di sessione.

Implicazione:

  • Anche se molte sessioni fanno pochissimo lavoro utile, il sistema continua a pagare il costo fisso di bootstrap dei subprocess claude -p.
  • Se i 540 session start/h provengono da uno o più orchestratori contemporanei, il problema resta: il budget viene bruciato in spawn ridondanti e sessioni che partono già morte.

2. Due control plane diversi per il bug bounty loop

Nel repo convivono almeno due approcci:

  • bugbounty/PERPETUAL-HUNTING-LOOP.sh
  • bugbounty/loop-manager.sh

In più, .claude/skills/bb-loop/SKILL.md dichiara comportamento "rate-limit aware", ma il path standard documentato e usato (PERPETUAL-HUNTING-LOOP.sh) non implementa quella protezione in modo robusto.

Questo è un forte segnale di drift architetturale: lo stesso sistema può essere avviato in modi diversi, con garanzie diverse.

3. Static prompt tax molto alto nelle skill principali

Stime conservative fatte con chars / 4 come proxy token.

File misurati:

  • CLAUDE.md: ~6.6K token
  • .claude/skills/pentest/SKILL.md: ~41.6K token
  • .claude/skills/test-injection/SKILL.md + supporting files: ~107.4K token
  • .claude/skills/test-auth/SKILL.md + supporting files: ~82.4K token
  • .claude/skills/test-access/SKILL.md + supporting files: ~57.5K token
  • .claude/skills/test-client/SKILL.md + supporting files: ~30.0K token
  • .claude/skills/test-logic/SKILL.md + supporting files: ~25.7K token
  • .claude/skills/test-api/SKILL.md + supporting files: ~24.0K token
  • .claude/skills/test-ssrf/SKILL.md + supporting files: ~19.7K token

Esempi di costo base teorico per un flusso bb-session -> bb-hunt -> pentest -> skill:

  • hunt injection: ~161.8K token statici
  • hunt auth: ~136.8K token statici
  • hunt access: ~111.9K token statici
  • hunt logic: ~80.0K token statici
  • hunt ssrf: ~74.1K token statici

Questa è la parte più importante del piano: il progetto è fortissimo metodologicamente, ma la metodologia è impacchettata in documenti runtime troppo grandi e troppo duplicati.

4. Parallelismo che moltiplica il costo base

File:

  • CLAUDE.md
  • .claude/skills/pentest/SKILL.md
  • .claude/skills/bb-hunt/SKILL.md

Il repo descrive:

  • wave dispatch
  • micro-agent paralleli
  • endpoint split
  • dual-engine
  • free-roaming finale

Il problema non è il parallelismo in sé, ma il fatto che ogni subagent sembra ereditare o ricaricare pacchetti istruzionali molto pesanti. Quindi il costo base viene moltiplicato per:

  • numero di wave
  • numero di skill attivate
  • numero di split per endpoint
  • numero di programmi testati in parallelo

5. Analisi AI del proxy attiva di default

File:

  • dashboard/backend/app/services/proxy_analyzer.py
  • dashboard/backend/app/main.py
  • dashboard/backend/app/models.py
  • dashboard/backend/app/schemas.py

Osservazioni:

  • proxy_analyzer_loop() viene avviato automaticamente in main.py
  • ProxySession.auto_analyze ha default True
  • l'analyzer manda batch di traffico a claude -p
  • batch ogni 20 secondi
  • minimo 3 request, massimo 25 request per batch
  • body request/response troncati ma comunque inclusi nel prompt

Implicazione:

  • In sessioni con Burp/Caido attivo, si può avere un secondo canale di consumo token parallelo al pentest principale.
  • Questo canale è particolarmente costoso in BB/recon aggressivo dove passano molti duplicati o richieste a basso valore.

6. Artifact explosion locale

Misure su bugbounty/:

  • .prompt-*: 7160 file, ~17.2 MB
  • .session-prompt-*: 2021 file, ~5.68 MB
  • perpetual-hunting-console.log: ~9.23 MB
  • PERPETUAL-HUNTING.log: ~5.13 MB
  • PROGRAM-MONITOR.log: ~3.28 MB

Note importanti:

  • Questi file non sono automaticamente token billable solo perché esistono.
  • Però dimostrano che il sistema ha generato migliaia di invocazioni/sottosessioni.
  • Inoltre aumentano il rischio di tool output inutilmente verboso e di search/glob locali che rientrano poi nel contesto.

7. Grande quantità di materiale locale che può gonfiare tool context

Misure indicative:

  • .claude/skills: ~6.57 MB
  • .claude/worktrees: ~102.67 MB
  • payloads: ~145.65 MB
  • ingest/data: ~25.74 MB
  • dashboard/frontend/node_modules: ~348.14 MB

Queste directory non sono il problema diretto del billing Claude in sé, ma sono ottimi candidati a:

  • output di search troppo larghi
  • tool context inutile
  • risposte CLI troppo verbose
  • rischio di letture accidentali del workspace

Cosa NON considero root cause primaria

--verbose

Vedo --verbose in diversi claude -p. Questo può aumentare log e rumore operativo, ma non lo considero il principale responsabile del burn token finché non c'è prova che cambi davvero il contenuto inviato al modello in modo sostanziale.

I file .prompt-* da soli

I prompt dump sono soprattutto una traccia del problema, non la causa primaria del billing. La causa è il numero di subprocess, non il fatto che il prompt venga anche scritto su disco.

Root Cause Ranking

Priorità 1: Loop senza cooldown reale e senza single-flight

Questo è il bug operativo più costoso e meno controverso da correggere.

Segnali:

  • spawn continuo dopo rate limit
  • troppe sessioni per unità di tempo
  • evidenza di più orchestratori o più run che scrivono negli stessi log

Priorità 2: Skill pack monolitici e costosi

Il progetto ha tantissima conoscenza valida, ma è caricata in runtime in modo troppo largo. Il costo fisso per skill è enorme.

Priorità 3: Parallelismo senza "skinny context"

Il fork/dispatch è corretto per qualità, ma se il parent context è grasso il parallelismo diventa moltiplicatore di prompt tax.

Priorità 4: Proxy AI analyzer sempre attivo

Può drenare parecchio in background, soprattutto su traffico ripetitivo o ad alta cardinalità.

Priorità 5: Rediscovery e reiniezione non differenziale

Soprattutto nel bug bounty di ritorno sullo stesso programma, il sistema rischia di pagare di nuovo discovery/prompt tax senza un delta reale della superficie.

Piano di ottimizzazione "trasparente"

Fase A. Correzioni immediate no-regression

Queste modifiche non riducono la copertura. Eliminano solo lavoro impossibile o duplicato.

  1. Single-instance lock obbligatorio
  2. Un solo orchestratore loop può essere attivo per account/workspace.
  3. PID lock o file lock atomico.
  4. Niente doppio start silenzioso.

  5. Rate-limit sentinel globale

  6. Se qualsiasi subprocess riceve out of extra usage, il control plane entra in cooldown globale.
  7. Nessun nuovo claude -p finché non arriva il reset o una finestra di retry credibile.

  8. Session invalidation per run "morte"

  9. Se una sessione termina in <= N turni o <= M secondi senza lavoro reale:

    • non viene considerata una vera hunt
    • non fa avanzare il loop in modo normale
    • attiva backoff, non immediate retry
  10. Unificare il control plane

  11. Un solo entrypoint ufficiale.
  12. bb-loop, PERPETUAL-HUNTING-LOOP.sh e loop-manager.sh devono convergere su una sola semantica.

  13. Log rotation e prompt dump fuori dal repo

  14. I dump restano disponibili per debug, ma vanno in directory runtime separata, rotata e ignorata.

Fase B. Riduzione del prompt tax senza perdere metodologia

  1. Dimagrire CLAUDE.md
  2. Lasciare solo:
    • invarianti globali
    • policy di sicurezza
    • routing essenziale
  3. Spostare i dettagli lunghi in file caricabili on demand.

  4. Spezzare le skill monolitiche in router + micro-pack

  5. Esempio test-injection:
    • router compatto
    • pack sqli
    • pack xss
    • pack ssti
    • pack xxe
    • pack cmdi
  6. La route o il signal tag decide quali pack caricare davvero.

  7. Lazy load dei supporting files

  8. Non tutto sempre acceso.
  9. Caricare solo il sotto-pack coerente con:

    • tecnologia rilevata
    • tipo di endpoint
    • segnali reali emersi in discovery
  10. Compiled prompt capsules

  11. Generare snapshot compatti e size-capped per:
    • prior knowledge
    • policy
    • hacktivity
    • change monitor
    • findings summary
  12. Tenere la storia completa su disco, ma iniettare solo il riassunto operativo.

  13. Eliminare testo duplicato

  14. Molte regole/safety/format/output/boilerplate sono ripetute.
  15. Tenerle una volta sola e referenziarle con un contratto molto più piccolo.

Fase C. Parallelismo più efficiente, stessa copertura

  1. Skinny parent before fork
  2. Prima di spawnare subagent, il parent produce un run brief molto compatto.
  3. I child ereditano:
    • target
    • scope
    • credenziali
    • crown jewels
    • endpoints assegnati
    • previous blockers
    • policy summary
  4. Non ereditano log narrativi e contesto verboso inutile.

  5. Deterministic-first, Opus-last

  6. Discovery, dedupe, clustering, fingerprinting, route preparation, policy parsing, traffic normalization:
    • modello più economico o codice deterministico
  7. Opus resta su:

    • reasoning profondo
    • exploit strategy
    • verification
    • chaining
    • high-confidence final finding decisions
  8. Equivalent-coverage batching

  9. Stesso coverage envelope, meno reasoning duplicato.
  10. Analizzare gruppi di endpoint equivalenti o request equivalenti, non 100 copie della stessa forma.

Fase D. Proxy analyzer senza perdita di efficacia

Qui serve prudenza, ma il piano può essere trasparente se fatto bene.

  1. Dedupe semantico del traffico
  2. Raggruppare per:
    • method
    • route normalized
    • param names
    • status code
    • response shape/hash
  3. Inviare a Claude:

    • primo esemplare
    • esemplari con delta significativo
    • request che matchano signal heuristics
  4. Threshold recall-oriented

  5. Mai scartare:

    • 4xx/5xx interessanti
    • nuove route
    • nuovi content-type
    • nuovi auth patterns
    • request con reflection, token, redirect, graphql, upload, webhook, callback
  6. Manual override sempre disponibile

  7. Realtime AI su singola request resta disponibile.
  8. L'ottimizzazione riguarda il batch continuo di background.

Fase E. Differential rediscovery per programmi già noti

Questa è importante per il BB loop continuativo.

Principio:

  • Se la superficie non è cambiata, non ha senso pagare ogni volta discovery completa come se il programma fosse nuovo.
  • Però non si deve perdere copertura.

Approccio trasparente:

  1. Eseguire sempre un freshness check leggero:
  2. headers
  3. homepage
  4. JS manifest/hash
  5. sitemap/robots diff
  6. fingerprint tech diff

  7. Se cambia qualcosa sopra soglia:

  8. full rediscovery

  9. Se non cambia nulla:

  10. reuse del baseline
  11. delta crawl mirato
  12. focus sugli untested endpoints e next steps storici

Questo non riduce la coverage: evita solo di rifare identica discovery su superficie invariata.

Proposta di rollout

Step 1: mettere in sicurezza il loop

Implementare subito:

  • singleton lock
  • rate-limit cooldown globale
  • invalidazione sessioni "morte"
  • unificazione entrypoint

Questa da sola dovrebbe tagliare una grossa parte del burn inutile.

Step 2: spezzare i pack più costosi

Partire da:

  • test-injection
  • test-auth
  • test-access

Sono quelli con il rapporto peggiore tra peso prompt e frequenza d'uso.

Step 3: ottimizzare proxy analyzer

Applicare dedupe semantico e background batching più selettivo.

Step 4: introdurre differential rediscovery

Soprattutto per bug bounty e loop perpetuo.

Step 5: validazione benchmark-driven

Solo dopo i primi 4 step, validare con shadow mode su benchmark e programmi storici.

Criteri di validazione no-regression

Una modifica entra solo se passa questi gate:

  1. Findings parity
  2. stesso numero di finding confermati o migliore

  3. Coverage parity

  4. stesso o migliore:

    • endpoint coverage
    • unique crown jewels touched
    • vuln class coverage
  5. Verification parity

  6. stesso tasso di finding verificati con PoC/evidence

  7. Chain parity

  8. nessun peggioramento nella rilevazione di chain

  9. Accepted-submission parity

  10. su dati storici BB: stesso o migliore tasso di accettazione

  11. Token efficiency

  12. token per finding confermato significativamente più basso

Benchmark consigliato per validazione

Usare almeno:

  • eval/lab già presenti nel repo
  • 2-3 programmi BB già lavorati con finding reali
  • 1 scenario con proxy analyzer attivo
  • 1 scenario con loop perpetuo e ritorno su programma già noto

Misurare:

  • total token
  • token per sessione
  • token per wave
  • token per finding
  • subprocess count
  • mean prompt size
  • mean turns per successful finding

Domande da far validare a Opus High

  1. Vedi rischi reali di perdita coverage nello spezzare le skill monolitiche in micro-pack signal-gated?
  2. Quali sezioni delle skill ritieni davvero "always-on" e quali possono diventare lazy load senza regressioni?
  3. Il proxy analyzer va lasciato default-on oppure va reso opt-in/thresholded per non drenare Max?
  4. Il differential rediscovery proposto è abbastanza conservativo per non perdere nuovi asset?
  5. C'è qualche area in cui sto sottostimando il peso del context: fork sui subagent?
  6. Come imposteresti un test shadow per dimostrare in modo rigoroso che il piano è trasparente?
  7. Tra test-injection, test-auth, test-access, quale conviene decomporre per primo per massimizzare riduzione token senza rischio?

Tesi finale

La mia conclusione è questa:

  • Il problema principale non è che state ragionando "troppo".
  • Il problema è che il sistema sta spendendo molti token su:
  • bootstrap ripetuto
  • loop in rate-limit
  • orchestrazione duplicata
  • pack istruzionali troppo larghi per ogni subprocess
  • AI analysis di traffico ripetitivo

Quindi la strada giusta non è semplificare il pentest. La strada giusta è:

  • rendere più magro il contesto strutturale
  • fermare gli spawn inutili
  • caricare conoscenza in modo selettivo
  • mantenere Opus sui passaggi davvero ad alto valore cognitivo

Questo è coerente con il vincolo fondamentale: ottimizzazioni trasparenti, zero downgrade metodologico.