
CLI de análise estática que escaneia bases de código em busca de injeção de prompt em LLM, exfiltração de dados, jailbreak e vulnerabilidades de agente/ferramenta inseguras. Executa totalmente offline, integra-se com CI/CD e gera relatórios em console, JSON e SARIF.
Ferramenta de análise estática que verifica seu código-fonte em busca de vulnerabilidades de injeção de prompt em LLM e segurança multimodal. Funciona offline, sem necessidade de chamadas de API.
O ContextHound está disponível em todo o seu fluxo de desenvolvimento e navegação:
| Ferramenta | O que faz | Instalação |
|---|---|---|
| CLI / pacote npm | Escaneia seu código-fonte em busca de vulnerabilidades de injeção de prompt. Integra-se com GitHub Actions, gera saída SARIF, JSON, HTML e muito mais. | npm install -g context-hound |
| Extensão VS Code | Achados inline enquanto você codifica, ações de código, canal de saída, barra de status. | VS Code Marketplace |
| Extensão de navegador | Pílula de varredura em tempo real em qualquer interface de chat de IA, painel DevTools para tráfego de API de LLM, scanner popup. Chrome e Firefox. | Firefox: Instale grátis · Chrome: aguardando revisão · código-fonte |
À medida que aplicações baseadas em LLM se tornam comuns em bases de código de produção, a injeção de prompt emergiu como uma das superfícies de ataque mais exploráveis; a maioria dos scanners de segurança não tem consciência disso.
O ContextHound traz análise estática para sua camada de prompt:
Ele se encaixa no seu fluxo de trabalho existente como um comando CLI, um script npm ou uma GitHub Action, com zero dependências externas.
Instalação global — adiciona o comando hound ao seu PATH:```bash
npm install -g context-hound
**Instalação por projeto** — restrito a um repositório, executado via `npx hound` ou um script npm:```bash
npm install --save-dev context-hound
Zero-install — sem necessidade de instalação, usa a cópia em cache do registro npm:```bash npx context-hound scan --dir .
---
## Início Rápido```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
Códigos de saída:
Adicione ao seu fluxo de trabalho para bloquear merges quando prompt risk for muito 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
Os resultados aparecerão na guia **Segurança > Varredura de código** do seu repositório. O formato `github-annotations` publica comentários inline em PRs e escreve uma tabela resumo no resumo da etapa do GitHub.
---
## Configuração
Execute `hound init` para gerar um `.contexthoundrc.json`, ou crie um 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"
}
Todas as configurações principais podem ser substituídas em tempo de execução sem editar o arquivo de configuração:
.houndignoreColoque um arquivo .houndignore na raiz do seu projeto para adicionar padrões de exclusão sem editar .contexthoundrc.json. Segue a mesma sintaxe de glob; linhas que começam com # são comentários.
Silencie um falso positivo conhecido diretamente no código-fonte — sem necessidade de desabilitar uma regra em todo o repositório. As diretivas são reconhecidas em qualquer tipo de arquivo (a sintaxe do comentário ao redor não importa):```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 [REGRA...]` — suprime achados na mesma linha
- `hound-disable-next-line [REGRA...]` — suprime achados na linha seguinte
- `hound-disable [REGRA...]` … `hound-enable [REGRA...]` — suprime um bloco (auto-fechado no final do arquivo)
- Omita IDs de regras para suprimir **todas** as regras naquele local; liste um ou mais (separados por espaço/vírgula) para restringir
- O texto após `--` é uma justificativa de forma livre, exibida nos relatórios
Execute com `--report-unused-suppressions` para listar diretivas que não correspondem mais a nenhum achado, para que supressões mortas possam ser limpas:```bash
hound scan --report-unused-suppressions
Ative um subconjunto curado de regras com --preset em vez de listar IDs. As pré-definições se unem a quaisquer includeRules que você já tenha, e várias podem ser combinadas:```bash
hound scan --preset owasp-llm-top10
hound scan --preset mcp,agentic
hound scan --list-presets # show all presets and their rule patterns
| Preset | Regras |
|--------|--------|
| `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 do pre-commit
O ContextHound inclui um hook do [pre-commit](https://pre-commit.com). Adicione-o ao seu `.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"]
Qualquer arquivo .js que exporte uma Rule ou Rule[] pode ser carregado como um 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 [];
},
};
Referencie-o em `.contexthoundrc.json`:```json
{ "plugins": ["./my-rule.js"] }
Plugin rules are subject to the same excludeRules, includeRules, and minConfidence filters as built-in rules.
Salve uma baseline após uma varredura inicial e, em seguida, relate apenas as descobertas que são novas em varreduras subsequentes:```bash
hound scan --format json --out baseline
hound scan --baseline baseline.json
As descobertas são correspondidas por `ruleId + file` — mudanças de linha não causam alertas falsos de novas descobertas.
### Apenas arquivos alterados (`--diff`)
Para portões rápidos de pull-request, escaneie apenas os arquivos que mudaram em relação a uma referência git em vez de toda a árvore:```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
Cobre arquivos confirmados, preparados, não preparados e rastreados-mas-não-ignorados. Se o git não estiver disponível ou a referência não puder ser resolvida (ex.: um clone superficial de CI), o ContextHound exibe um aviso e recai para uma varredura completa em vez de passar silenciosamente. Combine com --baseline para diffing no nível de descobertas, ou use --diff sozinho para o feedback mais rápido de PR.
Cada descoberta carrega pontos de risco calculados como:``` risk_points = severity_weight × confidence_multiplier
Pontuação|Nível|Ação sugerida
-------|-------|-----------------
0-29|🟢 Baixo|Nenhuma ação necessária
30-59|🟡 Médio|Revisar antes de mesclar
60-79|🟠 Alto|Corrigir antes de mesclar
80-100|🔴 Crítico|Bloquear implantação
Os pontos são totalizados, limitados a 100 e classificados:
Se seus prompts incluírem linguagem explícita de segurança (delimitadores de entrada, instruções de recusa de revelação, listas de permissão de ferramentas), os pontos de risco para esse prompt são reduzidos proporcionalmente.
---
## Regras
### A. Injeção (INJ)
| ID | Gravidade | Descrição |
|----|-----------|-----------|
| INJ-001 | Alto | Entrada direta do usuário concatenada no prompt sem delimitador |
| INJ-002 | Médio | Ausência de linguagem de delimitação "tratar conteúdo do usuário como dados" |
| INJ-003 | Alto | Contexto RAG/recuperado incluído sem separador não confiável |
| INJ-004 | Alto | Instruções de uso de ferramenta substituíveis por conteúdo do usuário |
| INJ-005 | Alto | Objeto de usuário serializado (`JSON.stringify`) interpolado diretamente em um modelo de prompt |
| INJ-006 | Médio | Comentário HTML contendo verbos de instrução ocultos em conteúdo controlado pelo usuário |
| INJ-007 | Médio | Entrada do usuário envolvida em delimitadores de cerca de código sem remover crases primeiro |
| INJ-008 | Alto | Dados de requisição HTTP (`req.body`, `req.query`, `req.params`) interpolados na string de modelo `role: "system"` |
| INJ-009 | Crítico | Corpo da requisição HTTP analisado diretamente como o array de mensagens — atacante controla papel e conteúdo |
| INJ-010 | Alto | Transcrição de rótulo de papel em texto simples (`User:`, `Assistant:`, `system:`) construída com concatenação de entrada não confiável |
| INJ-011 | Alto | Fonte do DOM do navegador ou URL (`window.location`, `document.cookie`, `getElementById`) alimentada diretamente na chamada LLM |
| INJ-012 | Alto | Histórico de conversa espalhado no array de mensagens sem sanitização |
| INJ-013 | Alto | Resultado de chamada de ferramenta/função inserido nas mensagens sem sanitização |
| INJ-014 | Alto | Saída do LLM canalizada como conteúdo de papel de usuário em uma chamada LLM subsequente |
| INJ-015 | Alto | Entrada externa não confiável (HTTP/CLI/DOM) flui para um prompt — **análise de contaminação** independente de nome, segue aliases, respeita sanitizadores |
### B. Exfiltração (EXF)
| ID | Gravidade | Descrição |
|----|-----------|-----------|
| EXF-001 | Crítico | Prompt faz referência a segredos, chaves de API ou credenciais |
| EXF-002 | Crítico | Prompt instrui o modelo a revelar o prompt do sistema ou instruções ocultas |
| EXF-003 | Alto | Prompt indica acesso a dados confidenciais ou privados |
| EXF-004 | Alto | Prompt inclui URLs internas ou nomes de host da infraestrutura |
| EXF-005 | Alto | Variável sensível (token, senha, chave) codificada como Base64 na saída |
| EXF-006 | Alto | Prompt completo ou array de mensagens registrado via `console.log` / `logger.*` sem edição |
| EXF-007 | Crítico | Valor secreto real incorporado no prompt junto com uma instrução "nunca revelar" |
### C. Jailbreak (JBK)
| ID | Gravidade | Descrição |
|----|-----------|-----------|
| JBK-001 | Crítico | Frase de jailbreak conhecida detectada ("ignore instructions", "DAN", etc.) |
| JBK-002 | Alto | Redação de segurança fraca ("always comply", "no matter what") |
| JBK-003 | Alto | Escotilha de escape de interpretação de papéis que compromete as restrições de segurança |
| JBK-004 | Alto | Agente instruído a agir sem confirmação ou revisão humana ("proceed automatically", "no confirmation needed") |
| JBK-005 | Alto | Instrução de apagamento de evidências ou ocultação de rastros ("delete logs", "leave no trace") |
| JBK-006 | Alto | Enquadramento de legitimidade de política combinado com uma solicitação de ação insegura ("as a penetration tester, escalate privileges") |
| JBK-007 | Alto | Falsificação de identidade do modelo — alega ser um modelo de IA diferente combinado com uma diretiva de bypass de segurança |
| JBK-008 | Alto | Ataque de compressão de prompt — instrução para comprimir ou resumir o prompt do sistema |
| JBK-009 | Alto | Injeção de instrução aninhada — comandos imperativos envolvidos em um enquadramento de "resumo/tradução seguro/inofensivo" |
### D. Uso Inseguro de Ferramenta (TOOL)
| ID | Gravidade | Descrição |
|----|-----------|-----------|
| TOOL-001 | Crítico | Execução de ferramenta sem limites ("run any command", "browse anywhere", substituição de shell por crases) |
| TOOL-002 | Médio | Uso de ferramenta descrito sem lista de permissão ou política de uso |
| TOOL-003 | Alto | Execução de código mencionada sem restrições de sandbox |
| TOOL-004 | Crítico | Descrição da ferramenta ou campo de esquema originado de uma variável controlada pelo usuário |
| TOOL-005 | Crítico | `name` da ferramenta ou `url` do endpoint originado de entrada controlada pelo usuário (`req.body`, `req.query`, etc.) |
### E. Injeção de Comandos (CMD)
Detecta padrões vulneráveis no código ao redor de ferramentas de IA, onde uma injeção de prompt bem-sucedida pode escalar para execução completa de comandos. Baseado em CVEs reais encontrados no Gemini CLI do Google pela Cyera Research Labs (2025).
| ID | Gravidade | Descrição |
|----|-----------|-----------|
| CMD-001 | Crítico | Comando shell construído com interpolação de variável não sanitizada — 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 | Filtragem de substituição de comando incompleta: bloqueia `$()` mas não crases, ou vice-versa |
| CMD-003 | Alto | Caminho de arquivo de `glob.sync` ou `readdirSync` usado diretamente em um comando shell sem sanitização |
| CMD-004 | Crítico | Python `subprocess.run`/`subprocess.call` invocado com `shell=True` e um argumento de comando variável ou f-string |
| CMD-005 | Crítico | PHP `shell_exec`, `system`, `passthru`, `exec`, ou `popen` chamado com um argumento `$variable` |
### F. Envenenamento de RAG (RAG)
Detecta erros arquiteturais em pipelines de Geração Aumentada por Recuperação (RAG) que permitem que conteúdo recuperado ou ingerido substitua instruções de nível de sistema.
| ID | Gravidade | Descrição |
|----|-----------|-----------|
| RAG-001 | Alto | Conteúdo recuperado ou externo atribuído a `role: "system"` em um array de mensagens |
| RAG-002 | Alto | Frases semelhantes a instruções ("system prompt:", "always return", "never redact") detectadas dentro de um loop de ingestão de documentos |
| RAG-003 | Alto | Armazenamento de memória do agente escrito diretamente a partir de entrada controlada pelo usuário sem validação |
| RAG-004 | Médio | Prompt instrui o modelo a tratar o contexto recuperado como prioridade máxima, substituindo as instruções do desenvolvedor |
| RAG-005 | Médio | Recuperação sem proveniência — blocos inseridos no prompt sem verificação de metadados de origem |
| RAG-006 | Alto | Nenhum filtro de ACL ou nível de confiança aplicado antes da recuperação entrar no prompt |
### G. Codificação (ENC)
Detecta técnicas de injeção e evasão baseadas em codificação onde Base64 ou codificações similares são usadas para contrabandear instruções através de filtros baseados em string.
| ID | Gravidade | Descrição |
|----|-----------|-----------|
| ENC-001 | Médio | `atob`, `btoa`, ou `Buffer.from(x, 'base64')` chamado em uma variável controlada pelo usuário próximo à construção do prompt |
| ENC-002 | Alto | Caracteres de controle Unicode ocultos (espaços de largura zero, sobreposições bidi) detectados próximos a palavras-chave de instrução |
### H. Manipulação de Saída (OUT)
Cobre o lado da saída do pipeline LLM — como sua aplicação consome as respostas do modelo. O consumo inseguro pode transformar uma carga útil de injeção de prompt em uma exploração a nível de aplicação.
| ID | Gravidade | Descrição |
|----|-----------|-----------|
| OUT-001 | Crítico | `JSON.parse()` (JS/TS) ou `json.loads()` (Python) chamado na saída do LLM sem validação de esquema (Zod, AJV, Joi, Pydantic, Marshmallow, etc.) |
| OUT-002 | Crítico | Markdown ou HTML gerado pelo LLM renderizado sem DOMPurify ou sanitizador equivalente |
| OUT-003 | Crítico | Saída do LLM usada diretamente como argumento para `exec()`, `eval()`, ou `db.query()` |
| OUT-004 | Crítico | Python `eval()` ou `exec()` chamado com saída gerada pelo LLM como argumento |
### I. Multimodal (VIS)
Cobre violações de fronteira de confiança específicas para pipelines de visão, áudio/vídeo e OCR. Entradas multimodais são um vetor de injeção emergente: um atacante que controla uma URL de imagem, um arquivo de áudio ou um documento escaneado pode usar os padrões dessas regras para contrabandear instruções para o modelo.
| ID | Gravidade | Descrição |
|----|-----------|-----------|
| VIS-001 | Crítico | URL de imagem ou dados base64 fornecidos pelo usuário encaminhados para uma API de visão (gpt-4o, Claude 3, Gemini Vision) sem validação de domínio ou MIME |
| VIS-002 | Crítico | `fs.readFile`/`readFileSync` chamado com um caminho controlado pelo usuário em um arquivo que também constrói uma mensagem de API de visão — path traversal para entrada multimodal |
| VIS-003 | Alto | Saída de transcrição de áudio/vídeo (Whisper, AssemblyAI, Deepgram, etc.) alimentada diretamente nas mensagens do prompt sem sanitização — envenenamento de RAG via fonte de áudio |
| VIS-004 | Alto | Saída de OCR (Tesseract, Google Vision) interpolada em uma mensagem `role: "system"` ou variável de prompt do sistema |
### J. Marketplace de Skills (SKL) — v1.1
Segmenta arquivos `SKILL.md` do OpenClaw e quaisquer arquivos markdown dentro de diretórios `skills/`. Dispara em ataques de autoautoria, carregamento remoto de skills, instruções injetadas, despacho inseguro de comandos, acesso a caminhos sensíveis, alegações de escalada de privilégio e credenciais codificadas em frontmatter YAML.
| ID | Gravidade | Descrição |
|----|-----------|-----------|
| SKL-001 | Crítico | Corpo da skill instrui o agente a escrever ou modificar outros arquivos de skill — ataque de autoautoria que persiste entre reinicializações do agente |
| SKL-002 | Crítico | Corpo da skill instrui o agente a buscar ou carregar skills de uma URL externa — permite que o atacante altere o comportamento da skill após a instalação |
| SKL-003 | Crítico | Corpo da skill contém frases de injeção de prompt visando instruções principais do agente (`ignore previous instructions`, `you are now unrestricted`, etc.) |
| SKL-004 | Alto | Frontmatter da skill usa `command-dispatch: tool` com `command-arg-mode: raw` — encaminha entrada bruta do usuário para uma ferramenta, ignorando o raciocínio de segurança do modelo |
| SKL-005 | Alto | Corpo da skill faz referência a caminhos sensíveis do sistema de arquivos (`~/.ssh`, `~/.env`, `/etc/passwd`, `../../`) para o agente ler e potencialmente exfiltrar |
| SKL-006 | Alto | Corpo da skill alega privilégios elevados ou instrui o agente a substituir ou desabilitar outras skills instaladas |
| SKL-007 | Crítico | Valor de credencial codificado (chave de API, token, senha) encontrado no frontmatter YAML — exposto a qualquer pessoa que receba ou instale a skill |
| SKL-008 | Crítico | Heartbeat C2 — skill agenda busca remota periódica para sobrescrever silenciosamente suas próprias instruções após uma instalação limpa |
| SKL-009 | Crítico | Negação de identidade do agente — skill instrui o agente a negar ser IA, afirmar ser humano ou adotar uma persona enganosa |
| SKL-010 | Crítico | Evasão de scanner — skill contém texto explicitamente projetado para enganar ferramentas de auditoria de segurança |
| SKL-011 | Crítico | Persistência SOUL.md / IDENTITY.md — skill escreve instruções em arquivos de identidade do agente que sobrevivem à desinstalação |
| SKL-012 | Alto | Verme autopropagável — skill instrui o agente a se espalhar via SSH ou `curl\|bash` para hosts alcançáveis |
| SKL-013 | Alto | Transações financeiras autônomas — skill executa transações de criptomoedas ou mantém chaves privadas sem confirmação do usuário por transação |
> **Escaneando skills OpenClaw:** Execute `npx hound scan --dir ./skills` ou adicione `**/skills/**/*.md` e `**/SKILL.md` à sua configuração `include`. O ContextHound emite automaticamente arquivos de skill como `code-block` para análise de regras multilinha.
### K. Agentic (AGT) — v1.3 / v1.9
Segmenta riscos específicos de sistemas agentivos multi-etapa: loops de execução ilimitados, escritas de memória não validadas, vazamento de entrada do usuário no planejamento do agente, violações de fronteira de confiança entre agentes e lacunas de segurança de IA Agentiva da OWASP (ASI).
| ID | Gravidade | Descrição |
|----|-----------|-----------|
| AGT-001 | Crítico | Parâmetro de chamada de ferramenta recebe conteúdo do prompt do sistema — valor do argumento `tool_call`/`function_call` contendo conteúdos dos campos `system:` ou `instructions:` |
| AGT-002 | Alto | Loop do agente sem proteção de iteração ou tempo limite — sem `max_iterations`, `max_steps`, `max_turns`, `timeout`, ou `recursion_limit` na configuração ou código do agente |
| AGT-003 | Alto | Memória do agente escrita a partir de saída não validada do LLM — `memory.save()`, `memory.add()`, ou `vectorstore.upsert()` chamado com uma variável de resposta bruta do modelo |
| AGT-004 | Alto | Injeção de plano — entrada do usuário interpolada diretamente no prompt de planejamento, tarefa ou objetivo do agente sem um envoltório de fronteira de confiança |
| AGT-005 | Crítico | Agente confia em identidade declarada sem verificação criptográfica — decisão de confiança baseada no campo `agentId`, `sender`, `source`, ou `from_agent` sem verificação HMAC, JWT ou segredo compartilhado |
| AGT-006 | Alto | Saída bruta do agente encadeada como entrada para outro agente sem validação — `.run()`, `.invoke()`, ou `.generate()` chamado com `.output`/`.content`/`.result` de outro agente diretamente como argumento |
| AGT-007 | Crítico | Automodificação do agente — agente reescreve sua própria lista de `system_prompt`, `instructions`, ou `tools` com conteúdo gerado pelo LLM em tempo de execução |
| AGT-008 | Crítico | ASI03 — Agente chama `assumeRole`, `grantAccess`, ou `setPermissions` com um valor derivado da saída do LLM; escalada de privilégio via injeção de prompt |
| AGT-009 | Alto | ASI04 — Agente carrega uma ferramenta ou plugin em tempo de execução a partir de um caminho variável ou importação dinâmica, permitindo substituição na cadeia de suprimentos |
| AGT-010 | Alto | ASI07 — Saída bruta do agente encaminhada para outro agente via `send`/`route`/`dispatch` sem HMAC, assinatura JWT ou validação de esquema |
| AGT-011 | Alto | ASI08 — Erro de etapa do plano do agente capturado silenciosamente (sem relançamento, sem sinalizador de estado de erro); etapas subsequentes prosseguem com estado ruim ou incompleto |
### L. Segurança MCP (MCP) — v1.7 / v1.8
Cobre riscos de fronteira de confiança e cadeia de suprimentos específicos do Protocolo de Contexto de Modelo (MCP). O MCP introduz uma nova superfície de ataque: descrições de ferramentas, URLs de transporte, payloads de eventos e estado compartilhado entre servidores podem todos carregar payloads de injeção ou escalada de privilégio.
| ID | Gravidade | Descrição |
|----|-----------|-----------|
| MCP-001 | Crítico | Descrição da ferramenta MCP injetada no prompt do LLM sem sanitização — valor bruto de `tool.description` usado em `role: "system"` ou `messages.push()` |
| MCP-002 | Alto | Ferramenta MCP registrada com nome ou descrição dinâmica — primeiro argumento de `server.tool()` é uma variável ou template literal, permitindo ataques de rug-pull pós-aprovação |
| MCP-003 | Alto | Handler MCP sampling/createMessage sem proteção de aprovação humana — `setRequestHandler(CreateMessageRequestSchema)` sem verificação de `requireHumanApproval`, `confirm`, ou `approve` |
| MCP-004 | Médio | URL de transporte MCP construída a partir de variável — `SSEClientTransport` ou `WebSocketClientTransport` inicializado com `new URL(variable)` em vez de uma string estática |
| MCP-005 | Alto | Transporte stdio MCP usa `shell: true` — torna a string de comando interpolada pelo shell e injetável se algum argumento for controlado pelo usuário |
| MCP-006 | Crítico | MCP confused deputy — token de autenticação de requisição MCP encaminhado para API downstream sem revalidação; valor do cabeçalho `Authorization` originado diretamente de `request.params`, `context`, ou `event` |
| MCP-007 | Alto | Envenenamento de contexto entre MCP — armazenamento de contexto compartilhado/global escrito a partir da saída MCP sem verificação de hash, assinatura ou proveniência |
| MCP-008 | Alto | Comando de transporte stdio MCP carregado de caminho variável — campo `command:` de `StdioClientTransport`/`StdioServerTransport` é uma variável em vez de um literal de string estática |
| MCP-009 | Alto | ID de sessão MCP usado como decisão de autenticação sem verificação de expiração — comparação de igualdade de `sessionId`/`connectionId` sem TTL, `expiresAt`, ou proteção `isExpired` (ataque de repetição) |
| MCP-010 | Crítico | Payload de evento de transporte MCP injetado no contexto do LLM sem sanitização — `.data`, `.content`, ou `.payload` de evento/mensagem usado diretamente em `messages.push()` ou um campo `content:` |
---
## Exemplo de Saída```
=== 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 inclui um conjunto de dados de benchmark rotulado para medir taxas de falso-positivo e de detecção. Execute após a compilação:```bash
npm run benchmark
O benchmark analisa dois diretórios de fixtures:
| Directory | Propósito |
|---|---|
benchmarks/safe/ | 5 arquivos com padrões seguros genuínos — espere 0 descobertas |
benchmarks/unsafe/ | 8 arquivos com vulnerabilidades reais — uma regra cada |
Resultados na v1.4.0:``` File-level FP rate: 0.0% (0 / 5 safe files produced findings) Detection rate: 100.0% (8/8 expected findings triggered)
O benchmark sai com código 1 se forem encontrados falsos positivos ou falsos negativos, tornando-o adequado como um portão de qualidade de CI para alterações de regras. Para adicionar uma fixture, coloque um arquivo em `benchmarks/safe/` ou `benchmarks/unsafe/` e atualize `benchmarks/labels.json` com os achados esperados.
### Precisão / recall por regra
O benchmark também exibe uma **tabela de sinal por regra** (pior F1 primeiro) para que regras de baixa precisão sejam fáceis de identificar — verdadeiros/falsos positivos, falsos negativos, precisão, recall e F1 para cada regra rotulada. As contagens de FP vêm das fixtures de `safe/` (verdade fundamental: zero achados); TP/FN vêm das fixtures rotuladas de `unsafe/`. Passe `--report <caminho>` para também emitir um relatório JSON legível por máquina para painéis ou rastreamento de tendências de CI:```bash
npm run benchmark -- --report bench-report.json
A extensão de navegador ContextHound traz detecção em tempo real de injeção de prompt para Chrome e Firefox. Ela usa o mesmo mecanismo de regras que a CLI, compilado e empacotado localmente — sem requisições de rede, sem backend.
Status: A extensão do Firefox está disponível — instale dos Complementos do Firefox. A submissão do Chrome aguarda revisão da Web Store. Código-fonte disponível em github.com/IulianVOStrut/ContextHound-Extensions.
Pílula de escaneamento Um indicador leve aparece ao lado de qualquer entrada de chat de IA em qualquer site. Enquanto você digita, a extensão escaneia o texto com base em 70 regras de detecção e exibe uma pontuação de risco e descobertas em um painel suspenso — sem necessidade de navegação pela página.
Painel DevTools Abra as DevTools do navegador e selecione a guia ContextHound para monitorar o tráfego de API LLM em tempo real. A extensão intercepta requisições de saída para OpenAI, Anthropic, Google Gemini, Mistral, Groq, Cohere, DeepSeek e outros serviços, escaneando tanto o corpo da requisição quanto a resposta em busca de conteúdo de injeção. Um distintivo na barra de ferramentas reflete a maior pontuação de risco observada na sessão atual.
Scanner popup Clique no ícone da barra de ferramentas para colar e escanear qualquer texto manualmente. Útil para revisar um prompt ou instrução do sistema recebida de terceiros antes de usá-lo.
A API HAR das DevTools do Chrome e Firefox (onRequestFinished) não inclui de forma confiável os bytes do corpo da requisição para respostas de streaming/SSE, que a maioria dos serviços de chat de IA utiliza. A extensão resolve isso com uma abordagem em duas camadas:
chrome.webRequest.onBeforeRequest intercepta os bytes brutos da requisição no service worker antes que a requisição seja enviada, armazenando-os brevemente em chrome.storage.session (TTL: 5 minutos).onRequestFinished dispara e postData está ausente, a página DevTools busca o corpo armazenado em cache do service worker por meio de uma mensagem POP_BODY_CACHE.A extensão não coleta dados do usuário. Todo o escaneamento é local. Veja a política de privacidade.
Contribuições são bem-vindas. Para adicionar uma nova regra:
src/rules/ (ou crie um novo para uma nova categoria)src/rules/index.tstests/rules.test.tsnpm test para verificar se todos os testes passamMIT
| 95 regras de segurança | Em 14 categorias: injeção, exfiltração, jailbreak, uso inseguro de ferramentas, injeção de comandos, envenenamento de RAG, codificação, manipulação de saída, multimodal, marketplace de skills, agentivo, MCP, cadeia de suprimentos, DoS |
| Pontuação de risco numérica (0-100) | Pontuação normalizada por repositório com limites baixo, médio, alto e crítico |
| Detecção de mitigações | Linguagem de segurança explícita em seus prompts reduz sua pontuação |
| 7 formatos de saída | Console, JSON, SARIF, GitHub Annotations, Markdown, streaming JSONL e HTML interativo |
| GitHub Action incluída | Falha na CI em risco alto e envia resultados SARIF automaticamente |
| Varredura multi-linguagem | Detecta uso de API de LLM em Python, Go, Rust, Java, C#, PHP, Ruby, Swift, Kotlin, Vue, Bash — não apenas TypeScript/JavaScript |
| Filtragem de regras | excludeRules/includeRules com sintaxe prefixo-glob (CMD-*); filtro minConfidence |
| Cache incremental | .hound-cache.json pula arquivos não modificados em reexecuções; --no-cache para desabilitar |
| Sistema de plugins | Carregar regras personalizadas de arquivos .js locais via "plugins": ["./my-rule.js"] na configuração |
| Modo baseline / diff | --baseline results.json — relatar e falhar apenas em achados não presentes em uma varredura anterior |
| Modo observação | --watch rescaneia em alterações de arquivos e mostra achados delta |
| Varredura paralela | Processamento concorrente de arquivos (--concurrency <n>, padrão 8) |
| Totalmente offline | Sem chamadas de API, sem telemetria, sem dependências pagas |
| Código | Significado |
|---|
0 | Aprovado — pontuação abaixo do limiar, nenhuma violação de failOn |
1 | Erro não tratado ou argumentos inválidos |
2 | Limiar excedido — pontuação do repositório ≥ limiar, ou limiar de arquivo excedido |
3 | Violação de --fail-on — descoberta da gravidade especificada encontrada |
| Opção | Padrão | Descrição |
|---|
include | **/*.{ts,tsx,js,jsx,py,go,rs,java,kt,cs,php,rb,swift,vue,sh,bash,hs,md,txt,yaml,yml,json} | Padrões glob para escanear |
exclude | **/node_modules/**, **/dist/**, etc. | Padrões glob a ignorar |
threshold | 60 | Falha se a pontuação do repositório for igual ou superior a este valor (código de saída 2) |
formats | ["console"] | Formatos de saída: console, json, sarif, github-annotations, markdown, jsonl, html |
out | auto | Caminho base para saída de arquivo |
verbose | false | Mostrar correções e confiança por descoberta |
failOn | não definido | Código de saída 3 na primeira descoberta de: critical, high, ou medium |
maxFindings | não definido | Parar após N descobertas |
excludeRules | [] | IDs de regras ou globs de prefixo para pular (ex.: "CMD-*", "JBK-002") |
includeRules | [] | Executar apenas estes IDs de regras (vazio = executar todas) |
minConfidence | não definido | Pular regras abaixo desta confiança: low, medium, ou high |
failFileThreshold | não definido | Falhar (código de saída 2) se qualquer arquivo individual pontuar igual ou acima deste valor |
concurrency | 8 | Máximo de arquivos processados em paralelo |
cache | true | Ativar cache de escaneamento incremental (.hound-cache.json); defina false ou use --no-cache para desativar |
plugins | [] | Caminhos para plugins de regras .js locais; cada um deve exportar um Rule ou Rule[] |
baseline | não definido | Caminho para um relatório JSON anterior; apenas descobertas ausentes da linha de base são relatadas |
| Variável | Substitui |
|---|
HOUND_THRESHOLD | threshold |
HOUND_FAIL_ON | failOn |
HOUND_MIN_CONFIDENCE | minConfidence |
HOUND_VERBOSE | verbose (truthy: 1, true, yes) |
HOUND_CONFIG | caminho para o arquivo de configuração |