
CLI di analisi statica che scansiona i codebase per vulnerabilità di prompt injection nei LLM, esfiltrazione di dati, jailbreak e agent/strumenti non sicuri. Funziona completamente offline, si integra con CI/CD e produce report in console, JSON e SARIF.
Strumento di analisi statica che esamina il tuo codebase alla ricerca di vulnerabilità di sicurezza da prompt injection e multimodalità nei LLM. Funziona offline, senza bisogno di chiamate API.
ContextHound è disponibile in tutto il tuo flusso di sviluppo e navigazione:
| Strumento | Cosa fa | Installazione |
|---|---|---|
| CLI / pacchetto npm | Esamina il tuo codebase per vulnerabilità di prompt injection. Si integra con GitHub Actions, produce output SARIF, JSON, HTML e altro. | npm install -g context-hound |
| Estensione VS Code | Risultati inline mentre scrivi codice, code action, pannello di output, barra di stato. | VS Code Marketplace |
| Estensione browser | Pillola di scansione in tempo reale su qualsiasi interfaccia chat AI, pannello DevTools per il traffico API LLM, scanner popup. Chrome e Firefox. | Firefox: Installa gratuitamente · Chrome: in attesa di revisione · sorgente |
Con l'uso crescente di applicazioni basate su LLM nei codebase di produzione, il prompt injection è emerso come una delle superfici di attacco più sfruttabili; la maggior parte degli scanner di sicurezza non ne è consapevole.
ContextHound porta l'analisi statica al tuo livello di prompt:
Si integra nel tuo flusso di lavoro esistente come comando CLI, script npm o GitHub Action, con zero dipendenze esterne.
Installazione globale — aggiunge il comando hound al tuo PATH:```bash
npm install -g context-hound
**Installazione per progetto** — ambito a un singolo repo, eseguito tramite `npx hound` o uno script npm:```bash
npm install --save-dev context-hound
Zero-install — nessuna installazione necessaria, utilizza la copia cache del registro npm:```bash npx context-hound scan --dir .
## Avvio Rapido```bash
# Scaffold a config file
hound init
# Scan your project
hound scan --dir ./my-ai-project
# Or via npm script (scans current directory)
npm run hound
# Verbose output, shows remediations and confidence levels
hound scan --verbose
# Fail the build on any critical finding
hound scan --fail-on critical
# Export JSON and SARIF reports
hound scan --format console,json,sarif --out results
# GitHub Annotations (for CI step summaries)
hound scan --format github-annotations
# Markdown report with findings tables
hound scan --format markdown --out report
# Stream findings as JSONL (one JSON object per line)
hound scan --format jsonl | jq '.severity'
# List all rules
hound scan --list-rules
# Explain a rule (or a rule family by prefix)
hound explain INJ-001
hound explain PST --format json
# Fast PR gate — scan only files changed vs. origin/main
hound scan --diff
# Interactive HTML report (self-contained, open in browser)
hound scan --format html --out report
# Re-scan on file changes
hound scan --watch
# Parallel scanning (default is 8; tune for your machine)
hound scan --concurrency 16
# Disable incremental cache for a clean run
hound scan --no-cache
# Baseline mode — only report findings new since the last saved scan
hound scan --format json --out baseline # save a baseline
hound scan --baseline baseline.json # compare future scans against it
# Load a custom rule from a local plugin file
hound scan # plugin declared in .contexthoundrc.json "plugins" field
# Only run high-confidence rules
hound scan --config .contexthoundrc.json # set minConfidence: "high"
# Fail if any single file scores >= 40
hound scan --fail-file-threshold 40
Codici di uscita:
Aggiungi al tuo workflow per bloccare i merge quando il rischio del prompt è troppo alto:```yaml
name: Prompt Audit
on: [push, pull_request]
jobs: hound: runs-on: ubuntu-latest permissions: contents: read security-events: write
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- run: npm install -g context-hound
- run: hound scan --format console,sarif,github-annotations --out results.sarif
- name: Upload to GitHub Code Scanning
if: always()
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: results.sarif
I risultati appariranno nella scheda **Security > Code scanning** del tuo repository. Il formato `github-annotations` pubblica commenti PR in linea e scrive una tabella riepilogativa nel riepilogo dei passaggi di GitHub.
---
## Configurazione
Esegui `hound init` per creare uno scheletro di `.contexthoundrc.json`, oppure creane uno manualmente:```json
{
"include": ["**/*.ts", "**/*.js", "**/*.py", "**/*.go", "**/*.rs", "**/*.md", "**/*.txt", "**/*.yaml"],
"exclude": [
"**/node_modules/**",
"**/dist/**",
"**/tests/**",
"**/attacks/**"
],
"threshold": 60,
"formats": ["console", "sarif"],
"out": "results",
"verbose": false,
"failOn": "critical",
"maxFindings": 50,
"excludeRules": ["JBK-002"],
"includeRules": [],
"minConfidence": "medium",
"failFileThreshold": 80,
"concurrency": 8,
"cache": true,
"plugins": ["./rules/my-custom-rule.js"],
"baseline": "./baseline.json"
}
Tutte le impostazioni chiave possono essere sovrascritte in esecuzione senza modificare il file di configurazione:
.houndignorePosiziona un file .houndignore nella radice del tuo progetto per aggiungere pattern di esclusione senza modificare .contexthoundrc.json. Segue la stessa sintassi glob; le righe che iniziano con # sono commenti.
Silenzia un falso positivo noto direttamente nel sorgente — non è necessario disabilitare una regola a livello di repository. Le direttive sono riconosciute in qualsiasi tipo di file (la sintassi del commento circostante non ha importanza):```ts
// hound-disable-next-line INJ-001 -- userInput is a validated enum
const prompt = Summarise the ${userInput} report;
const cmd = run(${shell}); // hound-disable-line CMD-001
// hound-disable RAG-007 -- trusted internal corpus only context.push(doc.metadata.title); context.push(doc.metadata.author); // hound-enable RAG-007
- `hound-disable-line [RULE...]` — sopprime i risultati sulla stessa riga
- `hound-disable-next-line [RULE...]` — sopprime i risultati sulla riga successiva
- `hound-disable [RULE...]` … `hound-enable [RULE...]` — sopprime un blocco (chiuso automaticamente alla fine del file)
- Ometti gli ID delle regole per sopprimere **tutte** le regole in quella posizione; elenca uno o più (separati da spazio/virgola) per limitarlo
- Il testo dopo `--` è una giustificazione in formato libero, visualizzata nei rapporti
Esegui con `--report-unused-suppressions` per elencare le direttive che non corrispondono più a nessun risultato, in modo da poter eliminare le soppressioni morte:```bash
hound scan --report-unused-suppressions
Abilitare un sottoinsieme curato di regole con --preset invece di elencare ID. I preset si uniscono a qualsiasi includeRules già presenti, e diversi possono essere combinati:```bash
hound scan --preset owasp-llm-top10
hound scan --preset mcp,agentic
hound scan --list-presets # show all presets and their rule patterns
| Preimpostazione | Regole |
|--------|-------|
| `owasp-llm-top10` | INJ, JBK, EXF, OUT, RAG, TOOL, SCH, DOS, VIS |
| `injection` | INJ, RAG, ENC |
| `jailbreak` | JBK |
| `exfiltration` | EXF |
| `agentic` | AGT, MCP, TOOL |
| `mcp` | MCP |
| `supply-chain` | SCH |
| `prompt-files` | INJ, JBK, EXF, ENC, SKL |
### hook pre-commit
ContextHound include un [pre-commit](https://pre-commit.com) hook. Aggiungilo al tuo `.pre-commit-config.yaml`:```yaml
repos:
- repo: https://github.com/IulianVOStrut/ContextHound
rev: v2.0.0
hooks:
- id: contexthound
# optional — scan only changed files and fail on high-severity findings:
# args: ["--diff", "HEAD", "--fail-on", "high"]
Qualsiasi file .js che esporta un Rule o Rule[] può essere caricato come plugin:```js
// my-rule.js
module.exports = {
id: 'CUSTOM-001',
title: 'Proprietary data pattern in prompt',
severity: 'high',
confidence: 'high',
category: 'injection',
remediation: 'Remove internal identifiers from prompts.',
check(prompt) {
if (prompt.text.includes('INTERNAL_PATTERN')) {
return [{ evidence: 'INTERNAL_PATTERN', lineStart: 1, lineEnd: 1 }];
}
return [];
},
};
Riferiscilo in `.contexthoundrc.json`:```json
{ "plugins": ["./my-rule.js"] }
Le regole dei plugin sono soggette agli stessi filtri excludeRules, includeRules e minConfidence delle regole integrate.
Salva una baseline dopo una scansione iniziale, quindi segnala solo i risultati che sono nuovi nelle scansioni successive:```bash
hound scan --format json --out baseline
hound scan --baseline baseline.json
I risultati vengono abbinati tramite `ruleId + file` — gli spostamenti di riga non causano falsi avvisi di nuovi risultati.
### Solo file modificati (`--diff`)
Per gate di pull-request veloci, scansiona solo i file che sono cambiati rispetto a un ref git anziché l'intero albero:```bash
hound scan --diff # vs. origin/main (default)
hound scan --diff main # vs. a named branch
hound scan --diff HEAD~5 # vs. an arbitrary ref
Copre i file committed, staged, unstaged e non tracciati ma non ignorati. Se git non è disponibile o il ref non può essere risolto (es. un clone CI superficiale), ContextHound stampa un avviso e torna a una scansione completa invece di passare silenziosamente. Combina con --baseline per un diff a livello di risultati, o usa --diff da solo per il feedback più veloce nelle PR.
Ogni risultato porta punti di rischio calcolati come:``` risk_points = severity_weight × confidence_multiplier
I punti vengono totalizzati, con un massimo di 100, e classificati:
| Punteggio | Livello | Azione suggerita |
|-------|-------|-----------------|
| 0-29 | 🟢 Basso | Nessuna azione richiesta |
| 30-59 | 🟡 Medio | Revisione prima del merge |
| 60-79 | 🟠 Alto | Correzione prima del merge |
| 80-100 | 🔴 Critico | Blocca il deployment |
Se i tuoi prompt includono linguaggio di sicurezza esplicito (delimitatori di input, istruzioni di non rivelazione, liste consentite di strumenti), i punti di rischio per quel prompt vengono ridotti proporzionalmente.
---
## Regole
### A. Iniezione (INJ)
| ID | Severità | Descrizione |
|----|----------|-------------|
| INJ-001 | Alto | Input utente diretto concatenato nel prompt senza delimitatore |
| INJ-002 | Medio | Linguaggio di confine "tratta il contenuto utente come dati" mancante |
| INJ-003 | Alto | Contesto RAG/recuperato incluso senza separatore non fidato |
| INJ-004 | Alto | Istruzioni per l'uso degli strumenti sovrascrivibili dal contenuto utente |
| INJ-005 | Alto | Oggetto utente serializzato (`JSON.stringify`) interpolato direttamente in un template di prompt |
| INJ-006 | Medio | Commento HTML contenente istruzioni nascoste in contenuto controllato dall'utente |
| INJ-007 | Medio | Input utente racchiuso in delimitatori di code fence senza prima rimuovere i backtick |
| INJ-008 | Alto | Dati di richiesta HTTP (`req.body`, `req.query`, `req.params`) interpolati in stringa template `role: "system"` |
| INJ-009 | Critico | Corpo della richiesta HTTP analizzato direttamente come array di messaggi — l'attaccante controlla ruolo e contenuto |
| INJ-010 | Alto | Trascrizione etichetta-ruolo in testo semplice (`User:`, `Assistant:`, `system:`) costruita con concatenazione di input non fidato |
| INJ-011 | Alto | Sorgente DOM o URL del browser (`window.location`, `document.cookie`, `getElementById`) alimentata direttamente in una chiamata LLM |
| INJ-012 | Alto | Cronologia conversazione distribuita nell'array messaggi senza sanitizzazione |
| INJ-013 | Alto | Risultato di chiamata strumento/funzione inserito nei messaggi senza sanitizzazione |
| INJ-014 | Alto | Completamento LLM reindirizzato come contenuto ruolo-utente in una successiva chiamata LLM |
| INJ-015 | Alto | Input esterno non fidato (HTTP/CLI/DOM) fluisce in un prompt — **taint analysis** indipendente dal nome, segue alias, rispetta sanitizer |
### B. Exfiltrazione (EXF)
| ID | Severità | Descrizione |
|----|----------|-------------|
| EXF-001 | Critico | Il prompt fa riferimento a segreti, chiavi API o credenziali |
| EXF-002 | Critico | Il prompt istruisce il modello a rivelare il prompt di sistema o istruzioni nascoste |
| EXF-003 | Alto | Il prompt indica accesso a dati riservati o privati |
| EXF-004 | Alto | Il prompt include URL interni o hostname dell'infrastruttura |
| EXF-005 | Alto | Variabile sensibile (token, password, chiave) codificata in Base64 nell'output |
| EXF-006 | Alto | Prompt completo o array messaggi registrato tramite `console.log` / `logger.*` senza oscuramento |
| EXF-007 | Critico | Valore segreto effettivo incorporato nel prompt insieme a un'istruzione "non rivelare mai" |
### C. Jailbreak (JBK)
| ID | Severità | Descrizione |
|----|----------|-------------|
| JBK-001 | Critico | Frase di jailbreak nota rilevata ("ignora le istruzioni", "DAN", ecc.) |
| JBK-002 | Alto | Formulazione di sicurezza debole ("rispetta sempre", "a tutti i costi") |
| JBK-003 | Alto | Uscita dal role-play che mina i vincoli di sicurezza |
| JBK-004 | Alto | Agente istruito ad agire senza conferma o revisione umana ("procedi automaticamente", "nessuna conferma necessaria") |
| JBK-005 | Alto | Istruzione di cancellazione tracce o copertura ("cancella i log", "nessuna traccia") |
| JBK-006 | Alto | Inquadramento di legittimità della policy combinato con una richiesta di azione non sicura ("come penetration tester, alza i privilegi") |
| JBK-007 | Alto | Spoofing dell'identità del modello — afferma di essere un modello AI diverso combinato con una direttiva di bypass della sicurezza |
| JBK-008 | Alto | Attacco di compressione del prompt — istruzione di comprimere o riassumere il prompt di sistema |
| JBK-009 | Alto | Iniezione di istruzioni annidata — comandi imperativi racchiusi in una cornice di "riassunto/traduzione sicuro/innocuo" |
### D. Uso Non Sicuro degli Strumenti (TOOL)
| ID | Severità | Descrizione |
|----|----------|-------------|
| TOOL-001 | Critico | Esecuzione di strumento senza limiti ("esegui qualsiasi comando", "naviga ovunque", sostituzione backtick di shell) |
| TOOL-002 | Medio | Uso dello strumento descritto senza lista consentita o policy di utilizzo |
| TOOL-003 | Alto | Esecuzione di codice menzionata senza vincoli di sandboxing |
| TOOL-004 | Critico | Descrizione dello strumento o campo schema proveniente da una variabile controllata dall'utente |
| TOOL-005 | Critico | `name` dello strumento o `url` dell'endpoint proveniente da input controllato dall'utente (`req.body`, `req.query`, ecc.) |
### E. Iniezione di Comando (CMD)
Rileva pattern vulnerabili nel codice circostante agli strumenti AI, dove un'iniezione di prompt riuscita può degenerare in esecuzione completa di comandi. Informato da CVE reali trovati in Google Gemini CLI da Cyera Research Labs (2025).
| ID | Severità | Descrizione |
|----|----------|-------------|
| CMD-001 | Critico | Comando shell costruito con interpolazione di variabile non sanitizzata — JS/TS (`execSync(\`cmd ${var}\``), Python (`subprocess.run(f"cmd {var}")`), PHP (`shell_exec($var)`), Go (`exec.Command` + `fmt.Sprintf`), Rust (`Command::new` + `format!`) |
| CMD-002 | Alto | Filtraggio incompleto della sostituzione di comando: blocca `$()` ma non i backtick, o viceversa |
| CMD-003 | Alto | Percorso file da `glob.sync` o `readdirSync` usato direttamente in un comando shell senza sanitizzazione |
| CMD-004 | Critico | Python `subprocess.run`/`subprocess.call` invocato con `shell=True` e una variabile o argomento comando f-string |
| CMD-005 | Critico | PHP `shell_exec`, `system`, `passthru`, `exec` o `popen` chiamati con un argomento `$variable` |
### F. Avvelenamento RAG (RAG)
Rileva errori architetturali nelle pipeline di Retrieval-Augmented Generation che permettono a contenuti recuperati o inseriti di sovrascrivere istruzioni a livello di sistema.
| ID | Severità | Descrizione |
|----|----------|-------------|
| RAG-001 | Alto | Contenuto recuperato o esterno assegnato a `role: "system"` in un array di messaggi |
| RAG-002 | Alto | Frasi simili a istruzioni ("system prompt:", "restituisci sempre", "non oscurare mai") rilevate all'interno di un ciclo di ingestione di documenti |
| RAG-003 | Alto | Memoria agente scritta direttamente da input controllato dall'utente senza validazione |
| RAG-004 | Medio | Il prompt istruisce il modello a trattare il contesto recuperato come priorità massima, sovrascrivendo le istruzioni dello sviluppatore |
| RAG-005 | Medio | Recupero senza provenienza — chunk inseriti nel prompt senza controllo dei metadati della fonte |
| RAG-006 | Alto | Nessun filtro ACL o livello di fiducia applicato prima che il recupero entri nel prompt |
### G. Codifica (ENC)
Rileva tecniche di iniezione ed evasione basate su codifica dove Base64 o codifiche simili sono usate per introdurre istruzioni oltre i filtri basati su stringhe.
| ID | Severità | Descrizione |
|----|----------|-------------|
| ENC-001 | Medio | `atob`, `btoa` o `Buffer.from(x, 'base64')` chiamati su una variabile controllata dall'utente vicino alla costruzione del prompt |
| ENC-002 | Alto | Caratteri di controllo Unicode nascosti (spazi a larghezza zero, override bidirezionali) rilevati vicino a parole chiave di istruzione |
### H. Gestione dell'Output (OUT)
Copro il lato output della pipeline LLM — come la tua applicazione consuma le risposte del modello. Un consumo non sicuro può trasformare un payload di iniezione di prompt in uno sfruttamento a livello applicativo.
| ID | Severità | Descrizione |
|----|----------|-------------|
| OUT-001 | Critico | `JSON.parse()` (JS/TS) o `json.loads()` (Python) chiamati sull'output LLM senza validazione dello schema (Zod, AJV, Joi, Pydantic, Marshmallow, ecc.) |
| OUT-002 | Critico | Markdown o HTML generato da LLM renderizzato senza DOMPurify o sanitizer equivalente |
| OUT-003 | Critico | Output LLM usato direttamente come argomento per `exec()`, `eval()` o `db.query()` |
| OUT-004 | Critico | Python `eval()` o `exec()` chiamato con output generato da LLM come argomento |
### I. Multimodale (VIS)
Copro violazioni del confine di fiducia specifiche per pipeline di visione, audio/video e OCR. Gli input multimodali sono un vettore di iniezione emergente: un attaccante che controlla un URL immagine, un file audio o un documento scannerizzato può usare i pattern di queste regole per introdurre istruzioni nel modello.
| ID | Severità | Descrizione |
|----|----------|-------------|
| VIS-001 | Critico | URL immagine o dati base64 forniti dall'utente inoltrati a un'API di visione (gpt-4o, Claude 3, Gemini Vision) senza validazione del dominio o MIME |
| VIS-002 | Critico | `fs.readFile`/`readFileSync` chiamato con un percorso controllato dall'utente in un file che costruisce anche un messaggio API di visione — path traversal in input multimodale |
| VIS-003 | Alto | Output di trascrizione audio/video (Whisper, AssemblyAI, Deepgram, ecc.) alimentato direttamente nei messaggi del prompt senza sanitizzazione — avvelenamento RAG tramite sorgente audio |
| VIS-004 | Alto | Output OCR (Tesseract, Google Vision) interpolato in un messaggio `role: "system"` o variabile del prompt di sistema |
### J. Skills Marketplace (SKL) — v1.1
Target dei file `SKILL.md` di OpenClaw e di qualsiasi file markdown all'interno delle directory `skills/`. Si attiva su attacchi di auto-autorizzazione, caricamento remoto di skill, istruzioni iniettate, invio di comandi non sicuri, accesso a percorsi sensibili, affermazioni di escalation dei privilegi e credenziali hardcoded nel frontmatter YAML.
| ID | Severità | Descrizione |
|----|----------|-------------|
| SKL-001 | Critico | Il corpo della skill istruisce l'agente a scrivere o modificare altri file di skill — attacco di auto-autorizzazione che persiste tra riavvii dell'agente |
| SKL-002 | Critico | Il corpo della skill istruisce l'agente a recuperare o caricare skill da un URL esterno — permette all'attaccante di modificare il comportamento della skill dopo l'installazione |
| SKL-003 | Critico | Il corpo della skill contiene frasi di iniezione di prompt mirate alle istruzioni principali dell'agente ("ignora le istruzioni precedenti", "ora sei senza restrizioni", ecc.) |
| SKL-004 | Alto | Il frontmatter della skill usa `command-dispatch: tool` con `command-arg-mode: raw` — inoltra l'input utente grezzo a uno strumento, bypassando la ragione di sicurezza del modello |
| SKL-005 | Alto | Il corpo della skill fa riferimento a percorsi filesystem sensibili (`~/.ssh`, `~/.env`, `/etc/passwd`, `../../`) per far leggere all'agente e potenzialmente esfiltrare |
| SKL-006 | Alto | Il corpo della skill rivendica privilegi elevati o istruisce l'agente a sovrascrivere o disabilitare altre skill installate |
| SKL-007 | Critico | Valore di credenziale hardcoded (chiave API, token, password) trovato nel frontmatter YAML — esposto a chiunque riceva o installi la skill |
| SKL-008 | Critico | Heartbeat C2 — la skill pianifica un recupero remoto periodico per sovrascrivere silenziosamente le proprie istruzioni dopo un'installazione pulita |
| SKL-009 | Critico | Negazione dell'identità dell'agente — la skill istruisce l'agente a negare di essere un AI, dichiararsi umano o adottare una personalità ingannevole |
| SKL-010 | Critico | Evasione dello scanner — la skill contiene testo esplicitamente progettato per ingannare gli strumenti di auditing di sicurezza |
| SKL-011 | Critico | Persistenza SOUL.md / IDENTITY.md — la skill scrive istruzioni nei file di identità dell'agente che sopravvivono alla disinstallazione |
| SKL-012 | Alto | Verme auto-propagante — la skill istruisce l'agente a diffondersi tramite SSH o `curl\|bash` verso host raggiungibili |
| SKL-013 | Alto | Transazioni finanziarie autonome — la skill esegue transazioni crypto o detiene chiavi private senza conferma utente per singola transazione |
> **Scansione delle skill OpenClaw:** Esegui `npx hound scan --dir ./skills` o aggiungi `**/skills/**/*.md` e `**/SKILL.md` alla tua configurazione `include`. ContextHound emette automaticamente i file skill come `code-block` per l'analisi di regole multilinea.
### K. Agente (AGT) — v1.3 / v1.9
Target dei rischi specifici dei sistemi agentici multi-step: cicli di esecuzione senza limiti, scritture di memoria non validate, input utente che perde nella pianificazione degli agenti, violazioni del confine di fiducia inter-agente e lacune OWASP Agentic AI Security Issues (ASI).
| ID | Severità | Descrizione |
|----|----------|-------------|
| AGT-001 | Critico | Il parametro di chiamata dello strumento riceve il contenuto del prompt di sistema — valore dell'argomento `tool_call`/`function_call` contenente contenuti dei campi `system:` o `instructions:` |
| AGT-002 | Alto | Ciclo agente senza protezione di iterazione o timeout — nessun `max_iterations`, `max_steps`, `max_turns`, `timeout` o `recursion_limit` nella configurazione o nel codice dell'agente |
| AGT-003 | Alto | Memoria agente scritta da output LLM non validato — `memory.save()`, `memory.add()` o `vectorstore.upsert()` chiamati con una variabile di risposta modello grezza |
| AGT-004 | Alto | Iniezione di piano — input utente interpolato direttamente nel prompt di pianificazione, compito o obiettivo dell'agente senza un wrapper di confine di fiducia |
| AGT-005 | Critico | L'agente si fida dell'identità dichiarata senza verifica crittografica — decisione di fiducia basata sul campo `agentId`, `sender`, `source` o `from_agent` senza verifica HMAC, JWT o segreto condiviso |
| AGT-006 | Alto | Output grezzo dell'agente concatenato come input per un altro agente senza validazione — `.run()`, `.invoke()` o `.generate()` chiamato con l'`.output`/`.content`/`.result` di un altro agente direttamente come argomento |
| AGT-007 | Critico | Auto-modifica dell'agente — l'agente riscrive il proprio `system_prompt`, `instructions` o elenco `tools` con contenuto generato da LLM in fase di esecuzione |
| AGT-008 | Critico | ASI03 — L'agente chiama `assumeRole`, `grantAccess` o `setPermissions` con un valore derivato dall'output LLM; escalation dei privilegi tramite iniezione di prompt |
| AGT-009 | Alto | ASI04 — L'agente carica uno strumento o un plugin in fase di esecuzione da un percorso variabile o import dinamico, abilitando la sostituzione della supply chain |
| AGT-010 | Alto | ASI07 — Output grezzo dell'agente inoltrato a un altro agente tramite `send`/`route`/`dispatch` senza HMAC, firma JWT o validazione dello schema |
| AGT-011 | Alto | ASI08 — Errore del passo del piano dell'agente catturato silenziosamente (nessun rilancio, nessun flag di stato di errore); i passi successivi procedono su stato errato o incompleto |
### L. Sicurezza MCP (MCP) — v1.7 / v1.8
Copro i rischi di confine di fiducia e di supply chain specifici del Model Context Protocol. MCP introduce una nuova superficie di attacco: descrizioni degli strumenti, URL di trasporto, payload di eventi e stato condiviso cross-server possono trasportare payload di iniezione o escalation dei privilegi.
| ID | Severità | Descrizione |
|----|----------|-------------|
| MCP-001 | Critico | Descrizione dello strumento MCP iniettata nel prompt LLM senza sanitizzazione — valore grezzo `tool.description` usato in `role: "system"` o `messages.push()` |
| MCP-002 | Alto | Strumento MCP registrato con nome o descrizione dinamica — il primo argomento di `server.tool()` è una variabile o template literal, abilitando attacchi di rug-pull dopo l'approvazione |
| MCP-003 | Alto | Handler `sampling/createMessage` di MCP senza guardia di approvazione umana — `setRequestHandler(CreateMessageRequestSchema)` senza controllo `requireHumanApproval`, `confirm` o `approve` |
| MCP-004 | Medio | URL di trasporto MCP costruito da variabile — `SSEClientTransport` o `WebSocketClientTransport` inizializzato con `new URL(variable)` invece di una stringa statica |
| MCP-005 | Alto | Trasporto stdio MCP usa `shell: true` — rende la stringa di comando interpolabile dalla shell e iniettabile se un qualsiasi argomento è controllato dall'utente |
| MCP-006 | Critico | Confused deputy MCP — token di autenticazione da richiesta MCP inoltrato a API downstream senza ri-validazione; valore dell'intestazione `Authorization` prelevato direttamente da `request.params`, `context` o `event` |
| MCP-007 | Alto | Avvelenamento del contesto cross-MCP — archivio di contesto condiviso/globale scritto da output MCP senza controllo di hash, firma o provenienza |
| MCP-008 | Alto | Comando di trasporto stdio MCP caricato da percorso variabile — campo `command:` di `StdioClientTransport`/`StdioServerTransport` è una variabile anziché un letterale stringa statico |
| MCP-009 | Alto | ID sessione MCP usato come decisione di autenticazione senza controllo di scadenza — confronto di uguaglianza `sessionId`/`connectionId` senza guardia TTL, `expiresAt` o `isExpired` (attacco replay) |
| MCP-010 | Critico | Payload di evento di trasporto MCP iniettato nel contesto LLM senza sanitizzazione — `.data`, `.content` o `.payload` di evento/messaggio usato direttamente in `messages.push()` o un campo `content:` |
---
## Esempio di Output```
=== ContextHound Prompt Audit ===
src/prompts/assistant.ts (file score: 73)
[HIGH] INJ-001: Direct user input concatenation without delimiter
File: src/prompts/assistant.ts:12
Evidence: Answer the user's question: ${userInput}
Confidence: medium
Risk points: 23
Remediation: Wrap user input with clear delimiters (e.g., triple backticks)
and label it as "untrusted user content".
[CRITICAL] EXF-001: Prompt references secrets, API keys, or credentials
File: src/prompts/assistant.ts:8
Evidence: The database password is: secret123.
Confidence: high
Risk points: 50
Remediation: Remove all secret values from prompts. Use environment
variables server-side; never embed credentials in prompt text.
────────────────────────────────────────────────────────
Repo Risk Score: 87/100 (CRITICAL)
Threshold: 60
Total findings: 5
By severity: critical: 2 high: 2 medium: 1
✗ FAILED - score meets or exceeds threshold.
src/ ├── cli.ts # CLI entry point (Commander.js) ├── types.ts # Shared TypeScript types ├── config/ │ ├── defaults.ts # Default include/exclude globs and settings │ └── loader.ts # .contexthoundrc.json loader + env var overrides ├── scanner/ │ ├── discover.ts # File discovery via fast-glob │ ├── extractor.ts # Prompt extraction (raw, code, structured) │ ├── languages.ts # LLM API trigger patterns per language extension │ ├── cache.ts # Incremental scan cache (.hound-cache.json) │ └── pipeline.ts # Orchestrates the full scan; parallel + cache + plugins ├── rules/ │ ├── types.ts # Rule interface and scoring helpers │ ├── injection.ts # INJ-* rules │ ├── exfiltration.ts # EXF-* rules │ ├── jailbreak.ts # JBK-* rules │ ├── unsafeTools.ts # TOOL-* rules │ ├── commandInjection.ts # CMD-* rules │ ├── rag.ts # RAG-* rules │ ├── encoding.ts # ENC-* rules │ ├── outputHandling.ts # OUT-* rules │ ├── multimodal.ts # VIS-* rules │ ├── skills.ts # SKL-* rules │ ├── agentic.ts # AGT-* rules │ ├── mcp.ts # MCP-* rules │ ├── supplyChain.ts # SCH-* rules │ ├── dos.ts # DOS-* rules │ ├── mitigation.ts # Mitigation presence detection │ └── index.ts # Rule registry ├── runtime/ │ ├── index.ts # createGuard() — runtime message inspection API │ ├── inspect.ts # Core inspection logic for live message arrays │ └── types.ts # RuntimeMessage, InspectResult, GuardConfig types ├── scoring/ │ └── index.ts # Risk score calculation and rule filtering └── report/ ├── console.ts # ANSI-coloured terminal output ├── json.ts # JSON report builder ├── sarif.ts # SARIF 2.1.0 report builder ├── githubAnnotations.ts# GitHub Actions annotation formatter ├── markdown.ts # Markdown report with findings tables ├── jsonl.ts # JSONL streaming formatter └── html.ts # Self-contained interactive HTML report attacks/ # Example injection strings (not executed against models) tests/ ├── fixtures/ # Sample prompts for testing ├── rules.test.ts # Unit tests for all rules ├── scoring.test.ts # Unit tests for scoring logic ├── scanner.test.ts # Integration tests for the scan pipeline ├── extractor.test.ts # Unit tests for prompt extraction ├── formatters.test.ts # Unit tests for all report formatters ├── mitigation.test.ts # Unit tests for mitigation detection └── cli.test.ts # CLI integration tests (init, list-rules, exit codes) .github/ ├── action.yml # Reusable composite GitHub Action └── workflows/ └── context-hound.yml # CI workflow
---
## Benchmark
ContextHound include un dataset di benchmark etichettato per misurare i tassi di falsi positivi e di rilevamento. Eseguilo dopo la build:```bash
npm run benchmark
Il benchmark scansiona due directory di test:
| Directory | Scopo |
|---|---|
benchmarks/safe/ | 5 file con pattern sicuri autentici — aspettati 0 segnalazioni |
benchmarks/unsafe/ | 8 file con vulnerabilità reali — una regola ciascuno |
Risultati con v1.4.0:``` File-level FP rate: 0.0% (0 / 5 safe files produced findings) Detection rate: 100.0% (8/8 expected findings triggered)
Il benchmark termina con codice 1 se vengono rilevati falsi positivi o falsi negativi, rendendolo adatto come gate di qualità CI per le modifiche alle regole. Per aggiungere una fixture, inserisci un file in `benchmarks/safe/` o `benchmarks/unsafe/` e aggiorna `benchmarks/labels.json` con i risultati attesi.
### Precisione / richiamo per regola
Il benchmark stampa anche una **tabella dei segnali per regola** (dal peggior F1 al migliore) in modo che le regole con bassa precisione siano facili da individuare — veri/falsi positivi, falsi negativi, precisione, richiamo e F1 per ogni regola etichettata. I conteggi FP provengono dalle fixture `safe/` (ground truth: zero risultati); TP/FN provengono dalle fixture `unsafe/` etichettate. Passa `--report <path>` per emettere anche un report JSON leggibile dalla macchina per dashboard o monitoraggio delle tendenze CI:```bash
npm run benchmark -- --report bench-report.json
L'estensione per browser ContextHound porta il rilevamento in tempo reale delle iniezioni di prompt a Chrome e Firefox. Utilizza lo stesso motore di regole della CLI, compilato e raggruppato localmente — nessuna richiesta di rete, nessun backend.
Stato: L'estensione per Firefox è attiva — installa dai componenti aggiuntivi di Firefox. L'invio per Chrome è in attesa di revisione nel Web Store. Il codice sorgente è disponibile su github.com/IulianVOStrut/ContextHound-Extensions.
Pillola di scansione Un indicatore leggero appare accanto a qualsiasi input di chat AI su qualsiasi sito web. Mentre scrivi, l'estensione analizza il testo rispetto a 70 regole di rilevamento e mostra un punteggio di rischio e i risultati in un pannello a tendina — nessuna navigazione di pagina richiesta.
Pannello DevTools Apri gli strumenti di sviluppo del browser e seleziona la scheda ContextHound per monitorare il traffico live delle API LLM. L'estensione intercetta le richieste in uscita verso OpenAI, Anthropic, Google Gemini, Mistral, Groq, Cohere, DeepSeek e altri servizi, analizzando sia il corpo della richiesta che la risposta per contenuti di iniezione. Un badge sulla barra degli strumenti riflette il punteggio di rischio più alto visto nella sessione corrente.
Scanner popup Fai clic sull'icona della barra degli strumenti per incollare e analizzare manualmente qualsiasi testo. Utile per esaminare un prompt o un'istruzione di sistema ricevuti da terze parti prima di utilizzarli.
L'API HAR degli strumenti di sviluppo di Chrome e Firefox (onRequestFinished) non include in modo affidabile i byte del corpo della richiesta per le risposte di streaming/SSE, che la maggior parte dei servizi di chat AI utilizza. L'estensione risolve questo problema con un approccio a due livelli:
chrome.webRequest.onBeforeRequest intercetta i byte grezzi della richiesta nel service worker prima che la richiesta venga inviata, li memorizza brevemente nella cache in chrome.storage.session (TTL: 5 minuti).onRequestFinished viene attivato e postData è assente, la pagina degli strumenti di sviluppo recupera il corpo in cache dal service worker tramite un messaggio POP_BODY_CACHE.L'estensione non raccoglie dati utente. Tutta la scansione è locale. Vedi la politica sulla privacy.
I contributi sono benvenuti. Per aggiungere una nuova regola:
src/rules/ (o creane uno nuovo per una nuova categoria)src/rules/index.tstests/rules.test.tsnpm test per verificare che tutti i test siano superatiMIT
| 95 regole di sicurezza | In 14 categorie: injection, esfiltrazione, jailbreak, uso non sicuro di strumenti, command injection, avvelenamento RAG, codifica, gestione output, multimodalità, marketplace di skills, agentico, MCP, supply chain, DoS |
| Punteggio di rischio numerico (0-100) | Punteggio normalizzato a livello di repository con soglie bassa, media, alta e critica |
| Rilevamento mitigazioni | Linguaggio di sicurezza esplicito nei tuoi prompt riduce il punteggio |
| 7 formati di output | Console, JSON, SARIF, GitHub Annotations, Markdown, streaming JSONL e HTML interattivo |
| GitHub Action inclusa | Fallisce la CI su rischio alto e carica automaticamente i risultati SARIF |
| Scansione multi-linguaggio | Rileva l'uso di API LLM in Python, Go, Rust, Java, C#, PHP, Ruby, Swift, Kotlin, Vue, Bash — non solo TypeScript/JavaScript |
| Filtro regole | excludeRules/includeRules con sintassi prefix-glob (CMD-*); filtro minConfidence |
| Cache incrementale | .hound-cache.json salta i file invariati nelle esecuzioni successive; --no-cache per disabilitare |
| Sistema di plugin | Carica regole personalizzate da file .js locali tramite "plugins": ["./my-rule.js"] nella configurazione |
| Modalità baseline / diff | --baseline results.json — segnala e fallisce solo sui risultati non presenti in una scansione precedente |
| Modalità watch | --watch riesegue la scansione al cambiamento dei file e mostra i risultati delta |
| Scansione parallela | Elaborazione concorrente dei file (--concurrency <n>, default 8) |
| Completamente offline | Nessuna chiamata API, nessuna telemetria, nessuna dipendenza a pagamento |
| Codice | Significato |
|---|
0 | Superato — punteggio sotto la soglia, nessuna violazione di failOn |
1 | Errore non gestito o argomenti errati |
2 | Soglia superata — punteggio repo ≥ soglia, o soglia file superata |
3 | Violazione di --fail-on — rilevamento della gravità specificata trovato |
| Opzione | Predefinito | Descrizione |
|---|
include | **/*.{ts,tsx,js,jsx,py,go,rs,java,kt,cs,php,rb,swift,vue,sh,bash,hs,md,txt,yaml,yml,json} | Pattern glob da scansionare |
exclude | **/node_modules/**, **/dist/**, ecc. | Pattern glob da ignorare |
threshold | 60 | Fallisce se il punteggio del repository è uguale o superiore a questo valore (codice di uscita 2) |
formats | ["console"] | Formati di output: console, json, sarif, github-annotations, markdown, jsonl, html |
out | auto | Percorso base per l'output dei file |
verbose | false | Mostra rimedi e confidenza per ogni rilevamento |
failOn | non impostato | Codice di uscita 3 al primo rilevamento di: critical, high o medium |
maxFindings | non impostato | Ferma dopo N rilevamenti |
excludeRules | [] | ID regole o glob di prefisso da saltare (es. "CMD-*", "JBK-002") |
includeRules | [] | Esegui solo questi ID regola (vuoto = esegui tutti) |
minConfidence | non impostato | Salta regole al di sotto di questa confidenza: low, medium o high |
failFileThreshold | non impostato | Fallisce (codice di uscita 2) se un singolo file ha un punteggio uguale o superiore a questo valore |
concurrency | 8 | Massimo di file elaborati in parallelo |
cache | true | Abilita cache di scansione incrementale (.hound-cache.json); imposta false o usa --no-cache per disabilitare |
plugins | [] | Percorsi verso plugin di regole .js locali; ognuno deve esportare un Rule o Rule[] |
baseline | non impostato | Percorso verso un report JSON precedente; vengono riportati solo i rilevamenti assenti dalla baseline |
| Variabile | Sovrascrive |
|---|
HOUND_THRESHOLD | threshold |
HOUND_FAIL_ON | failOn |
HOUND_MIN_CONFIDENCE | minConfidence |
HOUND_VERBOSE | verbose (truthy: 1, true, yes) |
HOUND_CONFIG | percorso del file di configurazione |