
CLI d'analyse statique qui scanne les bases de code pour les injections de prompt LLM, les exfiltrations de données, les jailbreaks et les vulnérabilités liées aux agents/outils non sécurisés. Fonctionne entièrement hors ligne, s'intègre au CI/CD et produit des rapports console, JSON et SARIF.
Outil d'analyse statique qui scanne votre codebase à la recherche de vulnérabilités de sécurité liées à l'injection de prompt et au multimodèle LLM. Fonctionne hors ligne, sans appel d'API nécessaire.
ContextHound est disponible sur l'ensemble de votre flux de développement et de navigation :
| Outil | Fonction | Installation |
|---|---|---|
| CLI / package npm | Scanne votre codebase pour les vulnérabilités d'injection de prompt. S'intègre à GitHub Actions, génère des sorties SARIF, JSON, HTML, etc. | npm install -g context-hound |
| Extension VS Code | Résultats en ligne pendant que vous codez, actions de code, canal de sortie, barre d'état. | VS Code Marketplace |
| Extension navigateur | Pastille de scan en temps réel sur toute interface de chat IA, panneau DevTools pour le trafic API LLM, scanner popup. Chrome et Firefox. | Firefox : Installer gratuit · Chrome : en attente de validation · source |
Alors que les applications basées sur les LLM deviennent courantes dans les codebases de production, l'injection de prompt est apparue comme l'une des surfaces d'attaque les plus exploitables ; la plupart des scanners de sécurité n'en ont pas conscience.
ContextHound apporte l'analyse statique à votre couche de prompt :
Il s'intègre dans votre flux de travail existant en tant que commande CLI, script npm ou GitHub Action, sans dépendances externes.
Installation globale — ajoute la commande hound à votre PATH :```bash
npm install -g context-hound
**Installation par projet** — limité à un dépôt, s'exécute via `npx hound` ou un script npm :```bash
npm install --save-dev context-hound
Zero-install — aucune installation nécessaire, utilise la copie en cache du registre npm :```bash npx context-hound scan --dir .
---
## Démarrage rapide```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
Codes de sortie :
Ajoutez à votre workflow pour bloquer les fusions lorsque le risque de prompt est trop élevé :```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
Les résultats apparaîtront dans l'onglet **Security > Code scanning** de votre dépôt. Le format `github-annotations` publie des commentaires en ligne dans les PR et écrit un tableau récapitulatif dans le résumé de l'étape GitHub.
---
## Configuration
Exécutez `hound init` pour générer un `.contexthoundrc.json`, ou créez-en un manuellement :
```shell```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"
}
Tous les paramètres clés peuvent être remplacés à l'exécution sans modifier le fichier de configuration :
.houndignorePlacez un fichier .houndignore à la racine de votre projet pour ajouter des motifs d'exclusion sans modifier .contexthoundrc.json. Il suit la même syntaxe glob ; les lignes commençant par # sont des commentaires.
Supprimez un faux positif connu directement dans la source — pas besoin de désactiver une règle sur l'ensemble du dépôt. Les directives sont reconnues dans tout type de fichier (la syntaxe de commentaire environnante n'a pas d'importance) :```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...]` — supprimer les résultats sur la même ligne
- `hound-disable-next-line [RULE...]` — supprimer les résultats sur la ligne suivante
- `hound-disable [RULE...]` … `hound-enable [RULE...]` — supprimer un bloc (auto-fermé à la fin du fichier)
- Omettre les identifiants de règle pour supprimer **toutes** les règles à cet endroit ; en lister un ou plusieurs (séparés par un espace ou une virgule) pour le limiter.
- Le texte après `--` est une justification libre, apparaissant dans les rapports
Exécutez avec `--report-unused-suppressions` pour lister les directives qui ne correspondent plus à aucun résultat, afin de nettoyer les suppressions inutilisées :```bash
hound scan --report-unused-suppressions
Activez un sous-ensemble organisé de règles avec --preset au lieu de lister des identifiants. Les préréglages s'unissent avec tous les includeRules que vous avez déjà, et plusieurs peuvent être combinés :```bash
hound scan --preset owasp-llm-top10
hound scan --preset mcp,agentic
hound scan --list-presets # show all presets and their rule patterns
| Préréglage | Règles |
|--------|-------|
| `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 inclut un [hook pre-commit](https://pre-commit.com). Ajoutez-le à votre `.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"]
Tout fichier .js qui exporte un Rule ou Rule[] peut être chargé en tant que 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 [];
},
};
Référencez-le dans `.contexthoundrc.json` :```json
{ "plugins": ["./my-rule.js"] }
Les règles des plugins sont soumises aux mêmes filtres excludeRules, includeRules et minConfidence que les règles intégrées.
Enregistrez une ligne de base après une analyse initiale, puis signalez uniquement les constatations qui sont nouvelles dans les analyses suivantes :```bash
hound scan --format json --out baseline
hound scan --baseline baseline.json
Les résultats sont mis en correspondance par `ruleId + file` — les décalages de lignes ne provoquent pas de fausses alertes de nouvelles découvertes.
### Fichiers modifiés uniquement (`--diff`)
Pour des vérifications rapides dans les pull requests, analysez uniquement les fichiers qui ont changé par rapport à une référence git au lieu de l'ensemble de l'arborescence :```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
Couvre les fichiers validés, indexés, non indexés et non suivis mais pas ignorés. Si git est indisponible ou que la référence ne peut pas être résolue (ex. un clone superficiel CI), ContextHound affiche un avertissement et revient à une analyse complète plutôt que de passer silencieusement. Combinez avec --baseline pour une comparaison au niveau des constatations, ou utilisez --diff seul pour le feedback le plus rapide sur les PR.
Chaque constatation comporte des points de risque calculés comme suit :``` risk_points = severity_weight × confidence_multiplier
Les points sont totalisés, plafonnés à 100 et classifiés :
| Score | Niveau | Action suggérée |
|-------|--------|-----------------|
| 0-29 | 🟢 Faible | Aucune action requise |
| 30-59 | 🟡 Moyen | Réviser avant fusion |
| 60-79 | 🟠 Élevé | Corriger avant fusion |
| 80-100 | 🔴 Critique | Bloquer le déploiement |
Si vos prompts incluent un langage de sécurité explicite (délimiteurs d'entrée, instructions de refus de divulgation, listes d'autorisation d'outils), les points de risque pour ce prompt sont réduits proportionnellement.
---
## Rules
### A. Injection (INJ)
| ID | Séverité | Description |
|----|----------|-------------|
| INJ-001 | Élevé | Entrée utilisateur directe concaténée dans le prompt sans délimiteur |
| INJ-002 | Moyen | Absence de langage de délimitation « traiter le contenu utilisateur comme des données » |
| INJ-003 | Élevé | Contexte RAG/récupéré inclus sans séparateur non fiable |
| INJ-004 | Élevé | Instructions d'utilisation d'outils pouvant être remplacées par le contenu utilisateur |
| INJ-005 | Élevé | Objet utilisateur sérialisé (`JSON.stringify`) interpolé directement dans un template de prompt |
| INJ-006 | Moyen | Commentaire HTML contenant des verbes d'instruction cachés dans du contenu contrôlé par l'utilisateur |
| INJ-007 | Moyen | Entrée utilisateur encapsulée dans des délimiteurs de bloc de code sans supprimer les backticks d'abord |
| INJ-008 | Élevé | Données de requête HTTP (`req.body`, `req.query`, `req.params`) interpolées dans une chaîne de template `role: "system"` |
| INJ-009 | Critique | Corps de requête HTTP analysé directement comme le tableau `messages` — l'attaquant contrôle le rôle et le contenu |
| INJ-010 | Élevé | Transcription d'étiquette de rôle en texte clair (`User:`, `Assistant:`, `system:`) construite avec concaténation d'entrée non fiable |
| INJ-011 | Élevé | Source DOM du navigateur ou URL (`window.location`, `document.cookie`, `getElementById`) alimentée directement dans un appel LLM |
| INJ-012 | Élevé | Historique de conversation étalé dans le tableau `messages` sans assainissement |
| INJ-013 | Élevé | Résultat d'appel d'outil/fonction inséré dans `messages` sans assainissement |
| INJ-014 | Élevé | Completion LLM redirigée comme contenu de rôle utilisateur dans un appel LLM ultérieur |
| INJ-015 | Élevé | Entrée externe non fiable (HTTP/CLI/DOM) circule dans un prompt — analyse de contamination indépendante du nom, suit les alias, respecte les assainisseurs |
### B. Exfiltration (EXF)
| ID | Séverité | Description |
|----|----------|-------------|
| EXF-001 | Critique | Le prompt référence des secrets, clés API ou identifiants |
| EXF-002 | Critique | Le prompt demande au modèle de révéler le prompt système ou des instructions cachées |
| EXF-003 | Élevé | Le prompt indique un accès à des données confidentielles ou privées |
| EXF-004 | Élevé | Le prompt inclut des URL internes ou des noms d'hôte d'infrastructure |
| EXF-005 | Élevé | Variable sensible (token, mot de passe, clé) encodée en Base64 dans la sortie |
| EXF-006 | Élevé | Prompt complet ou tableau `messages` journalisé via `console.log` / `logger.*` sans rédaction |
| EXF-007 | Critique | Valeur secrète réelle intégrée dans le prompt avec une instruction « ne jamais révéler » |
### C. Jailbreak (JBK)
| ID | Séverité | Description |
|----|----------|-------------|
| JBK-001 | Critique | Phrase de jailbreak connue détectée (« ignore instructions », « DAN », etc.) |
| JBK-002 | Élevé | Formulation de sécurité faible (« always comply », « no matter what ») |
| JBK-003 | Élevé | Échappatoire de jeu de rôle qui compromet les contraintes de sécurité |
| JBK-004 | Élevé | Agent invité à agir sans confirmation ni révision humaine (« proceed automatically », « no confirmation needed ») |
| JBK-005 | Élevé | Instruction d'effacement de preuves ou de dissimulation (« delete logs », « leave no trace ») |
| JBK-006 | Élevé | Cadre de légitimité politique combiné à une demande d'action non sécurisée (« as a penetration tester, escalate privileges ») |
| JBK-007 | Élevé | Usurpation d'identité du modèle — prétend être un modèle d'IA différent combiné à une directive de contournement de sécurité |
| JBK-008 | Élevé | Attaque de compression de prompt — instruction de compresser ou résumer le prompt système |
| JBK-009 | Élevé | Injection d'instructions imbriquées — commandes impératives encapsulées dans un cadre de « résumé/traduction sûr/inoffensif » |
### D. Unsafe Tool Use (TOOL)
| ID | Séverité | Description |
|----|----------|-------------|
| TOOL-001 | Critique | Exécution d'outil sans limite (« run any command », « browse anywhere », substitution shell par backtick) |
| TOOL-002 | Moyen | Utilisation d'outil décrite sans liste d'autorisation ni politique d'utilisation |
| TOOL-003 | Élevé | Exécution de code mentionnée sans contraintes de sandboxing |
| TOOL-004 | Critique | Description d'outil ou champ de schéma provenant d'une variable contrôlée par l'utilisateur |
| TOOL-005 | Critique | Nom d'outil ou URL de point d'accès provenant d'une entrée contrôlée par l'utilisateur (`req.body`, `req.query`, etc.) |
### E. Command Injection (CMD)
Détecte les schémas vulnérables dans le code entourant les outils d'IA, où une injection de prompt réussie peut dégénérer en exécution complète de commande. Informé par des CVE réels trouvés dans le CLI Gemini de Google par Cyera Research Labs (2025).
| ID | Séverité | Description |
|----|----------|-------------|
| CMD-001 | Critique | Commande shell construite avec interpolation de variable non assainie — 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 | Élevé | Filtrage de substitution de commande incomplet : bloque `$()` mais pas les backticks, ou vice versa |
| CMD-003 | Élevé | Chemin de fichier provenant de `glob.sync` ou `readdirSync` utilisé directement dans une commande shell sans assainissement |
| CMD-004 | Critique | Python `subprocess.run`/`subprocess.call` invoqué avec `shell=True` et un argument de commande variable ou f-string |
| CMD-005 | Critique | PHP `shell_exec`, `system`, `passthru`, `exec`, ou `popen` appelé avec un argument `$variable` |
### F. RAG Poisoning (RAG)
Détecte les erreurs architecturales dans les pipelines RAG qui permettent au contenu récupéré ou ingéré de remplacer les instructions au niveau système.
| ID | Séverité | Description |
|----|----------|-------------|
| RAG-001 | Élevé | Contenu récupéré ou externe assigné à `role: "system"` dans un tableau `messages` |
| RAG-002 | Élevé | Phrases de type instruction (« system prompt: », « always return », « never redact ») détectées dans une boucle d'ingestion de documents |
| RAG-003 | Élevé | Stockage de mémoire d'agent écrit directement à partir d'une entrée contrôlée par l'utilisateur sans validation |
| RAG-004 | Moyen | Le prompt demande au modèle de traiter le contexte récupéré comme priorité absolue, ignorant les instructions du développeur |
| RAG-005 | Moyen | Récupération sans provenance — blocs insérés dans le prompt sans vérification des métadonnées source |
| RAG-006 | Élevé | Aucun filtre ACL ou de niveau de confiance appliqué avant que la récupération n'entre dans le prompt |
### G. Encoding (ENC)
Détecte les techniques d'injection et d'évasion basées sur l'encodage où Base64 ou des encodages similaires sont utilisés pour faire passer des instructions en contrebande au-delà des filtres basés sur les chaînes.
| ID | Séverité | Description |
|----|----------|-------------|
| ENC-001 | Moyen | `atob`, `btoa`, ou `Buffer.from(x, 'base64')` appelé sur une variable contrôlée par l'utilisateur près de la construction du prompt |
| ENC-002 | Élevé | Caractères de contrôle Unicode cachés (espaces de largeur nulle, remplacements bidi) détectés près de mots-clés d'instruction |
### H. Output Handling (OUT)
Couvre le côté sortie du pipeline LLM — comment votre application consomme les réponses du modèle. Une consommation non sécurisée peut transformer une charge utile d'injection de prompt en une exploitation au niveau de l'application.
| ID | Séverité | Description |
|----|----------|-------------|
| OUT-001 | Critique | `JSON.parse()` (JS/TS) ou `json.loads()` (Python) appelé sur la sortie LLM sans validation de schéma (Zod, AJV, Joi, Pydantic, Marshmallow, etc.) |
| OUT-002 | Critique | Markdown ou HTML généré par LLM rendu sans DOMPurify ou assainisseur équivalent |
| OUT-003 | Critique | Sortie LLM utilisée directement comme argument pour `exec()`, `eval()`, ou `db.query()` |
| OUT-004 | Critique | Python `eval()` ou `exec()` appelé avec une sortie générée par LLM comme argument |
### I. Multimodal (VIS)
Couvre les violations de frontière de confiance spécifiques aux pipelines vision, audio/vidéo et OCR. Les entrées multimodales sont un vecteur d'injection émergent : un attaquant qui contrôle une URL d'image, un fichier audio ou un document scanné peut utiliser les schémas de ces règles pour faire passer des instructions en contrebande dans le modèle.
| ID | Séverité | Description |
|----|----------|-------------|
| VIS-001 | Critique | URL d'image ou données base64 fournies par l'utilisateur transmises à une API de vision (gpt-4o, Claude 3, Gemini Vision) sans validation de domaine ou de type MIME |
| VIS-002 | Critique | `fs.readFile`/`readFileSync` appelé avec un chemin contrôlé par l'utilisateur dans un fichier qui construit également un message d'API de vision — traversée de chemin dans l'entrée multimodale |
| VIS-003 | Élevé | Sortie de transcription audio/vidéo (Whisper, AssemblyAI, Deepgram, etc.) alimentée directement dans les messages du prompt sans assainissement — empoisonnement RAG via source audio |
| VIS-004 | Élevé | Sortie OCR (Tesseract, Google Vision) interpolée dans un message `role: "system"` ou une variable de prompt système |
### J. Skills Marketplace (SKL) — v1.1
Cible les fichiers `SKILL.md` d'OpenClaw et tout fichier markdown dans les répertoires `skills/`. Se déclenche sur les attaques d'auto-rédaction, le chargement distant de compétences, les instructions injectées, la répartition de commandes non sécurisée, l'accès aux chemins sensibles, les revendications d'élévation de privilèges et les identifiants codés en dur dans le frontmatter YAML.
| ID | Séverité | Description |
|----|----------|-------------|
| SKL-001 | Critique | Le corps de la compétence demande à l'agent d'écrire ou modifier d'autres fichiers de compétence — attaque d'auto-rédaction qui persiste entre les redémarrages de l'agent |
| SKL-002 | Critique | Le corps de la compétence demande à l'agent de récupérer ou charger des compétences depuis une URL externe — permet à l'attaquant de modifier le comportement de la compétence après installation |
| SKL-003 | Critique | Le corps de la compétence contient des phrases d'injection de prompt ciblant les instructions principales de l'agent (`ignore previous instructions`, `you are now unrestricted`, etc.) |
| SKL-004 | Élevé | Le frontmatter de la compétence utilise `command-dispatch: tool` avec `command-arg-mode: raw` — transmet l'entrée utilisateur brute à un outil, contournant le raisonnement de sécurité du modèle |
| SKL-005 | Élevé | Le corps de la compétence référence des chemins sensibles du système de fichiers (`~/.ssh`, `~/.env`, `/etc/passwd`, `../../`) pour que l'agent les lise et potentiellement les exfiltre |
| SKL-006 | Élevé | Le corps de la compétence revendique des privilèges élevés ou demande à l'agent de remplacer ou désactiver d'autres compétences installées |
| SKL-007 | Critique | Valeur d'identifiant codée en dur (clé API, token, mot de passe) trouvée dans le frontmatter YAML — exposée à quiconque reçoit ou installe la compétence |
| SKL-008 | Critique | C2 par battement de cœur — la compétence planifie une récupération périodique à distance pour écraser silencieusement ses propres instructions après une installation propre |
| SKL-009 | Critique | Déni d'identité de l'agent — la compétence demande à l'agent de nier être une IA, de prétendre être humain, ou d'adopter un personnage trompeur |
| SKL-010 | Critique | Évitement anti-scanner — la compétence contient du texte explicitement conçu pour tromper les outils d'audit de sécurité |
| SKL-011 | Critique | Persistance SOUL.md / IDENTITY.md — la compétence écrit des instructions dans des fichiers d'identité de l'agent qui survivent à la désinstallation |
| SKL-012 | Élevé | Ver auto-propagateur — la compétence demande à l'agent de se propager via SSH ou `curl\|bash` vers des hôtes accessibles |
| SKL-013 | Élevé | Transactions financières autonomes — la compétence exécute des transactions crypto ou détient des clés privées sans confirmation utilisateur par transaction |
> **Analyse des compétences OpenClaw :** Exécutez `npx hound scan --dir ./skills` ou ajoutez `**/skills/**/*.md` et `**/SKILL.md` à votre configuration `include`. ContextHound émet automatiquement les fichiers de compétence en tant que `code-block` pour l'analyse de règles multi-lignes.
### K. Agentic (AGT) — v1.3 / v1.9
Cible les risques spécifiques aux systèmes agentiques multi-étapes : boucles d'exécution sans limites, écritures mémoire non validées, fuite d'entrée utilisateur dans la planification agentique, violations de frontière de confiance inter-agents et lacunes de l'OWASP Agentic AI Security Issues (ASI).
| ID | Séverité | Description |
|----|----------|-------------|
| AGT-001 | Critique | Le paramètre d'appel d'outil reçoit le contenu du prompt système — valeur d'argument `tool_call`/`function_call` contenant le contenu des champs `system:` ou `instructions:` |
| AGT-002 | Élevé | Boucle d'agent sans garde d'itération ou de timeout — pas de `max_iterations`, `max_steps`, `max_turns`, `timeout`, ou `recursion_limit` dans la configuration ou le code de l'agent |
| AGT-003 | Élevé | Mémoire d'agent écrite à partir d'une sortie LLM non validée — `memory.save()`, `memory.add()`, ou `vectorstore.upsert()` appelé avec une variable de réponse brute du modèle |
| AGT-004 | Élevé | Injection de plan — entrée utilisateur interpolée directement dans le prompt de planification, de tâche ou d'objectif de l'agent sans wrapper de frontière de confiance |
| AGT-005 | Critique | L'agent fait confiance à l'identité revendiquée sans vérification cryptographique — décision de confiance basée sur le champ `agentId`, `sender`, `source`, ou `from_agent` sans vérification HMAC, JWT ou secret partagé |
| AGT-006 | Élevé | Sortie brute d'agent chaînée en entrée d'un autre agent sans validation — `.run()`, `.invoke()`, ou `.generate()` appelé avec `.output`/`.content`/`.result` d'un autre agent directement comme argument |
| AGT-007 | Critique | Auto-modification de l'agent — l'agent réécrit son propre `system_prompt`, `instructions`, ou liste `tools` avec du contenu généré par LLM à l'exécution |
| AGT-008 | Critique | ASI03 — L'agent appelle `assumeRole`, `grantAccess`, ou `setPermissions` avec une valeur dérivée de la sortie LLM ; escalade de privilèges via injection de prompt |
| AGT-009 | Élevé | ASI04 — L'agent charge un outil ou plugin à l'exécution depuis un chemin variable ou une importation dynamique, permettant la substitution de la chaîne d'approvisionnement |
| AGT-010 | Élevé | ASI07 — Sortie brute d'agent transmise à un autre agent via `send`/`route`/`dispatch` sans HMAC, signature JWT, ou validation de schéma |
| AGT-011 | Élevé | ASI08 — Erreur d'étape de plan d'agent capturée silencieusement (pas de relance, pas de drapeau d'état d'erreur) ; les étapes en aval continuent sur un état mauvais ou incomplet |
### L. MCP Security (MCP) — v1.7 / v1.8
Couvre les risques de frontière de confiance et de chaîne d'approvisionnement spécifiques au Model Context Protocol. MCP introduit une nouvelle surface d'attaque : les descriptions d'outils, les URL de transport, les charges utiles d'événements et l'état partagé entre serveurs peuvent tous transporter des charges utiles d'injection ou d'escalade de privilèges.
| ID | Séverité | Description |
|----|----------|-------------|
| MCP-001 | Critique | Description d'outil MCP injectée dans le prompt LLM sans assainissement — valeur brute `tool.description` utilisée dans `role: "system"` ou `messages.push()` |
| MCP-002 | Élevé | Outil MCP enregistré avec un nom ou une description dynamique — le premier argument de `server.tool()` est une variable ou un template literal, permettant des attaques de retrait de tapis après approbation |
| MCP-003 | Élevé | Gestionnaire MCP sampling/createMessage sans garde d'approbation humaine — `setRequestHandler(CreateMessageRequestSchema)` sans vérification `requireHumanApproval`, `confirm`, ou `approve` |
| MCP-004 | Moyen | URL de transport MCP construite à partir d'une variable — `SSEClientTransport` ou `WebSocketClientTransport` initialisé avec un `new URL(variable)` au lieu d'une chaîne statique |
| MCP-005 | Élevé | Le transport stdio MCP utilise `shell: true` — rend la chaîne de commande interpolée par le shell et injectable si un argument est contrôlé par l'utilisateur |
| MCP-006 | Critique | Député confus MCP — token d'authentification de la requête MCP transmis à l'API en aval sans re-validation ; valeur de l'en-tête `Authorization` provenant directement de `request.params`, `context`, ou `event` |
| MCP-007 | Élevé | Empoisonnement de contexte inter-MCP — magasin de contexte partagé/global écrit à partir de la sortie MCP sans vérification de hachage, signature ou provenance |
| MCP-008 | Élevé | Commande de transport stdio MCP chargée depuis un chemin variable — le champ `command:` de `StdioClientTransport`/`StdioServerTransport` est une variable plutôt qu'une chaîne littérale statique |
| MCP-009 | Élevé | ID de session MCP utilisé comme décision d'authentification sans vérification d'expiration — comparaison d'égalité `sessionId`/`connectionId` sans TTL, `expiresAt`, ou garde `isExpired` (attaque par rejeu) |
| MCP-010 | Critique | Payload d'événement de transport MCP injecté dans le contexte LLM sans assainissement — `.data`, `.content`, ou `.payload` d'événement/message utilisé directement dans `messages.push()` ou un champ `content:` |
---
## Example 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 fournit un jeu de données de référence étiqueté pour mesurer les taux de faux positifs et de détection. Exécutez-le après la compilation :```bash
npm run benchmark
Le benchmark analyse deux répertoires de fixtures :
| Répertoire | Objectif |
|---|---|
benchmarks/safe/ | 5 fichiers avec des motifs sûrs authentiques — attendez-vous à 0 résultats |
benchmarks/unsafe/ | 8 fichiers avec de vraies vulnérabilités — une règle chacune |
Résultats sur v1.4.0 :``` File-level FP rate: 0.0% (0 / 5 safe files produced findings) Detection rate: 100.0% (8/8 expected findings triggered)
Le benchmark se termine avec le code 1 si des faux positifs ou des faux négatifs sont trouvés, ce qui le rend adapté comme porte de qualité CI pour les modifications de règles. Pour ajouter un fixture, déposez un fichier dans `benchmarks/safe/` ou `benchmarks/unsafe/` et mettez à jour `benchmarks/labels.json` avec les résultats attendus.
### Précision / rappel par règle
Le benchmark imprime également un **tableau de signal par règle** (le pire F1 en premier) afin que les règles à faible précision soient faciles à repérer — vrais/faux positifs, faux négatifs, précision, rappel et F1 pour chaque règle étiquetée. Les comptes FP proviennent des fixtures `safe/` (vérité terrain : zéro résultat) ; les TP/FN proviennent des fixtures `unsafe/` étiquetées. Passez `--report <path>` pour également émettre un rapport JSON lisible par machine pour les tableaux de bord ou le suivi des tendances CI :```bash
npm run benchmark -- --report bench-report.json
L'extension de navigateur ContextHound apporte la détection en temps réel d'injections de prompt à Chrome et Firefox. Elle utilise le même moteur de règles que la CLI, compilé et empaqueté localement — aucune requête réseau, aucun backend.
Statut : L'extension Firefox est disponible — installer depuis les modules complémentaires Firefox. La soumission Chrome est en attente de validation par le Chrome Web Store. Le code source est disponible sur github.com/IulianVOStrut/ContextHound-Extensions.
Pilule de scan Un indicateur léger apparaît à côté de toute zone de saisie de chat IA sur n'importe quel site. Pendant que vous tapez, l'extension analyse le texte selon 70 règles de détection et affiche un score de risque et les résultats dans un panneau déroulant — aucune navigation vers une autre page n'est nécessaire.
Panneau DevTools Ouvrez les DevTools du navigateur et sélectionnez l'onglet ContextHound pour surveiller le trafic API LLM en direct. L'extension intercepte les requêtes sortantes vers OpenAI, Anthropic, Google Gemini, Mistral, Groq, Cohere, DeepSeek et d'autres services, en analysant à la fois le corps de la requête et la réponse pour détecter du contenu d'injection. Un badge dans la barre d'outils reflète le score de risque le plus élevé observé dans la session en cours.
Scanner contextuel Cliquez sur l'icône de la barre d'outils pour coller et analyser manuellement n'importe quel texte. Utile pour examiner un prompt ou une instruction système reçue d'un tiers avant de l'utiliser.
L'API HAR des DevTools de Chrome et Firefox (onRequestFinished) n'inclut pas de manière fiable les octets du corps de requête pour les réponses streaming/SSE, que la plupart des services de chat IA utilisent. L'extension résout ce problème avec une approche à deux couches :
chrome.webRequest.onBeforeRequest intercepte les octets bruts de la requête dans le service worker avant que la requête ne soit envoyée, les met en cache brièvement dans chrome.storage.session (TTL : 5 minutes).onRequestFinished se déclenche et que postData est absent, la page DevTools récupère le corps mis en cache depuis le service worker via un message POP_BODY_CACHE.L'extension ne collecte aucune donnée utilisateur. Toute analyse est locale. Voir la politique de confidentialité.
Les contributions sont les bienvenues. Pour ajouter une nouvelle règle :
src/rules/ (ou créez-en un nouveau pour une nouvelle catégorie)src/rules/index.tstests/rules.test.tsnpm test pour vérifier que tous les tests passentMIT
| 95 règles de sécurité | Dans 14 catégories : injection, exfiltration, jailbreak, utilisation non sécurisée d'outils, injection de commande, empoisonnement RAG, encodage, gestion des sorties, multimodal, marketplace de compétences, agentique, MCP, chaîne d'approvisionnement, DoS |
| Score de risque numérique (0-100) | Score au niveau du dépôt normalisé avec seuils bas, moyen, élevé et critique |
| Détection des mesures d'atténuation | Un langage de sécurité explicite dans vos prompts réduit votre score |
| 7 formats de sortie | Console, JSON, SARIF, Annotations GitHub, Markdown, flux JSONL, et HTML interactif |
| GitHub Action inclus | Échoue le CI en cas de risque élevé et télécharge automatiquement les résultats SARIF |
| Scanne plusieurs langages | Détecte l'utilisation d'API LLM en Python, Go, Rust, Java, C#, PHP, Ruby, Swift, Kotlin, Vue, Bash — pas seulement TypeScript/JavaScript |
| Filtrage des règles | excludeRules/includeRules avec syntaxe de glob préfixé (CMD-*) ; filtre minConfidence |
| Cache incrémental | .hound-cache.json ignore les fichiers inchangés lors des réexécutions ; --no-cache pour désactiver |
| Système de plugins | Charger des règles personnalisées depuis des fichiers .js locaux via "plugins": ["./my-rule.js"] dans la configuration |
| Mode baseline / diff | --baseline results.json — ne signaler et échouer que sur les résultats absents d'un scan précédent |
| Mode surveillance | --watch rescanner lors de modifications de fichiers et afficher les résultats delta |
| Scan parallèle | Traitement concurrent des fichiers (--concurrency <n>, défaut 8) |
| Totalement hors ligne | Aucun appel d'API, aucune télémétrie, aucune dépendance payante |
| Code | Signification |
|---|
0 | Réussi — score en dessous du seuil, pas de violation de failOn |
1 | Erreur non gérée ou mauvais arguments |
2 | Seuil dépassé — score du dépôt ≥ seuil, ou seuil de fichier dépassé |
3 | Violation de --fail-on — constatation de la sévérité spécifiée trouvée |
| Option | Défaut | Description |
|---|
include | **/*.{ts,tsx,js,jsx,py,go,rs,java,kt,cs,php,rb,swift,vue,sh,bash,hs,md,txt,yaml,yml,json} | Modèles glob à analyser |
exclude | **/node_modules/**, **/dist/**, etc. | Modèles glob à ignorer |
threshold | 60 | Échouer si le score du dépôt est égal ou supérieur à cette valeur (code de sortie 2) |
formats | ["console"] | Formats de sortie : console, json, sarif, github-annotations, markdown, jsonl, html |
out | auto | Chemin de base pour la sortie des fichiers |
verbose | false | Afficher les corrections et la confiance par résultat |
failOn | non défini | Code de sortie 3 dès le premier résultat de type : critical, high ou medium |
maxFindings | non défini | Arrêter après N résultats |
excludeRules | [] | Identifiants de règle ou globs de préfixe à ignorer (ex. "CMD-*", "JBK-002") |
includeRules | [] | Exécuter uniquement ces identifiants de règle (vide = tout exécuter) |
minConfidence | non défini | Ignorer les règles en dessous de ce niveau de confiance : low, medium ou high |
failFileThreshold | non défini | Échouer (code de sortie 2) si un seul fichier a un score égal ou supérieur à cette valeur |
concurrency | 8 | Nombre maximal de fichiers traités en parallèle |
cache | true | Activer le cache d'analyse incrémentielle (.hound-cache.json) ; définir false ou utiliser --no-cache pour désactiver |
plugins | [] | Chemins vers des plugins de règles .js locaux ; chacun doit exporter une Rule ou un Rule[] |
baseline | non défini | Chemin vers un rapport JSON précédent ; seuls les résultats absents de la référence sont signalés |
| Variable | Remplace |
|---|
HOUND_THRESHOLD | threshold |
HOUND_FAIL_ON | failOn |
HOUND_MIN_CONFIDENCE | minConfidence |
HOUND_VERBOSE | verbose (truthy : 1, true, yes) |
HOUND_CONFIG | chemin vers le fichier de configuration |