IulianVOStrut/ContextHound
GitHub: IulianVOStrut/ContextHound
一款面向LLM应用的静态安全扫描工具,用于检测提示词注入、数据泄露、越狱攻击等AI场景特有的漏洞风险。
Stars: 1 | Forks: 0
# ContextHound
## [](https://github.com/IulianVOStrut/ContextHound/actions/workflows/context-hound.yml)
[](https://www.npmjs.com/package/context-hound)
[](https://nodejs.org)
[](https://www.typescriptlang.org)
[](LICENSE)
## 为什么选择 ContextHound?
随着 LLM 驱动的应用程序在生产代码库中变得普遍,提示词注入已成为最易被利用的攻击面之一;大多数安全扫描器对此毫无察觉。
ContextHound 将静态分析引入您的提示词层:
- 在**注入路径**到达模型之前捕获它们
- 标记提示词中嵌入的**泄露凭据和内部基础设施**信息
- 检测系统提示词中**易受越狱攻击的措辞**
- 识别可能被武器化的**不受限 Agent 工具使用**
- 检测 **RAG 语料库投毒**以及作为系统指令注入的检索内容
- 捕获**基于编码的走私**(绕过字符串过滤器的 Base64 指令)
- 标记**不安全的 LLM 输出消费**:无 Schema 验证的 JSON 以及未经过滤器处理的 Markdown
- 检测**多模态攻击面**:用户提供的发送到 Vision API 的图像 URL、通过 Vision 消息文件读取进行的路径遍历、输入到提示词的转录输出,以及注入到系统指令中的 OCR 文本
- 标记**Agent 风险**:无界限的 Agent 循环、未经验证的内存写入、计划注入,以及接收系统提示词内容的工具参数
- 奖励**良好的安全实践**:提示词中的缓解措施会降低您的风险评分
它以 CLI 命令、`npm` 脚本或 GitHub Action 的形式融入您现有的工作流,且零外部依赖。
## 功能特性
| | |
|---|---|
| **70 条安全规则** | 涵盖 11 个类别:注入、数据泄露、越狱、不安全工具使用、命令注入、RAG 投毒、编码、输出处理、多模态、技能市场、Agent |
| **数值风险评分 (0-100)** | 标准化的仓库级评分,设有低、中、高和严重阈值 |
| **缓解检测** | 提示词中明确的安全语言会降低您的评分 |
| **7 种输出格式** | Console、JSON、SARIF、GitHub Annotations、Markdown、JSONL streaming 和交互式 HTML |
| **包含 GitHub Action** | 在高风险时中断 CI 并自动上传 SARIF 结果 |
| **多语言扫描** | 检测 Python、Go、Rust、Java、C#、PHP、Ruby、Swift、Kotlin、Vue、Bash 中的 LLM API 使用情况 —— 不仅仅是 TypeScript/JavaScript |
| **规则过滤** | 支持前缀通配符语法的 `excludeRules`/`includeRules`(如 `CMD-*`);`minConfidence` 过滤器 |
| **增量缓存** | `.hound-cache.json` 在重新运行时跳过未更改的文件;使用 `--no-cache` 禁用 |
| **插件系统** | 通过配置中的 `"plugins": ["./my-rule.js"]` 从本地 `.js` 文件加载自定义规则 |
| **基线 / 差异模式** | `--baseline results.json` —— 仅报告并警告先前扫描中不存在的发现 |
| **监视模式** | `--watch` 在文件更改时重新扫描并显示增量发现 |
| **并行扫描** | 并发文件处理(`--concurrency `,默认为 8) |
| **完全离线** | 无 API 调用,无遥测,无付费依赖 |
## 安装
**全局安装** —— 将 `hound` 命令添加到您的 PATH:
```
npm install -g context-hound
```
**单项目安装** —— 作用于单个仓库,通过 `npx hound` 或 npm script 运行:
```
npm install --save-dev context-hound
```
**零安装** —— 无需安装,使用缓存的 npm registry 副本:
```
npx context-hound scan --dir .
```
## 快速开始
```
# 搭建配置文件
hound init
# 扫描您的项目
hound scan --dir ./my-ai-project
# 或通过 npm script(扫描当前目录)
npm run hound
# 详细输出,显示修复建议和置信度级别
hound scan --verbose
# 在任何关键发现上使构建失败
hound scan --fail-on critical
# 导出 JSON 和 SARIF 报告
hound scan --format console,json,sarif --out results
# GitHub Annotations(用于 CI 步骤摘要)
hound scan --format github-annotations
# 包含发现表格的 Markdown 报告
hound scan --format markdown --out report
# 以 JSONL 流式传输发现(每行一个 JSON 对象)
hound scan --format jsonl | jq '.severity'
# 列出所有 68 条规则
hound scan --list-rules
# 交互式 HTML 报告(自包含,在浏览器中打开)
hound scan --format html --out report
# 文件更改时重新扫描
hound scan --watch
# 并行扫描(默认为 8;请根据您的机器调整)
hound scan --concurrency 16
# 禁用增量缓存以进行全新运行
hound scan --no-cache
# Baseline 模式 —— 仅报告自上次保存的扫描以来新增的发现
hound scan --format json --out baseline # save a baseline
hound scan --baseline baseline.json # compare future scans against it
# 从本地插件文件加载自定义规则
hound scan # plugin declared in .contexthoundrc.json "plugins" field
# 仅运行高置信度规则
hound scan --config .contexthoundrc.json # set minConfidence: "high"
# 如果任何单个文件得分 >= 40 则失败
hound scan --fail-file-threshold 40
```
**退出代码:**
| 代码 | 含义 |
|------|---------|
| `0` | 通过 —— 评分低于阈值,无 `failOn` 违规 |
| `1` | 未处理的错误或参数错误 |
| `2` | 超过阈值 —— 仓库评分 ≥ 阈值,或文件阈值超标 |
| `3` | `--fail-on` 违规 —— 发现了指定严重级别的发现 |
## GitHub Actions
添加到您的工作流中,以便在提示词风险过高时阻止合并:
```
# .github/workflows/context-hound.yml
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
```
发现结果将显示在您仓库的 **Security > Code scanning** 标签页中。`github-annotations` 格式会在 PR 中发布内联评论,并将汇总表写入 GitHub 步骤摘要。
## 配置
运行 `hound init` 以生成 `.contexthoundrc.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"
}
```
| 选项 | 默认值 | 描述 |
|--------|---------|-------------|
| `include` | `**/*.{ts,tsx,js,jsx,py,go,rs,java,kt,cs,php,rb,swift,vue,sh,bash,hs,md,txt,yaml,yml,json}` | 要扫描的 Glob 模式 |
| `exclude` | `**/node_modules/**`, `**/dist/**`, 等 | 要忽略的 Glob 模式 |
| `threshold` | `60` | 如果仓库评分达到或超过此值则失败(退出代码 2) |
| `formats` | `["console"]` | 输出格式:`console`、`json`、`sarif`、`github-annotations`、`markdown`、`jsonl`、`html` |
| `out` | auto | 文件输出的基础路径 |
| `verbose` | `false` | 显示每个发现的修复建议和置信度 |
| `failOn` | unset | 首次发现以下级别时退出代码 3:`critical`、`high` 或 `medium` |
| `maxFindings` | unset | 在 N 个发现后停止 |
| `excludeRules` | `[]` | 要跳过的规则 ID 或前缀 Glob(例如 `"CMD-*"`, `"JBK-002"`) |
| `includeRules` | `[]` | 仅运行这些规则 ID(空 = 运行所有) |
| `minConfidence` | unset | 跳过置信度低于此值的规则:`low`、`medium` 或 `high` |
| `failFileThreshold` | unset | 如果任何单个文件评分达到或超过此值则失败(退出代码 2) |
| `concurrency` | `8` | 并行处理的最大文件数 |
| `cache` | `true` | 启用增量扫描缓存(`.hound-cache.json`);设置为 `false` 或使用 `--no-cache` 禁用 |
| `plugins` | `[]` | 本地 `.js` 规则插件的路径;每个必须导出一个 `Rule` 或 `Rule[]` |
| `baseline` | unset | 先前 JSON 报告的路径;仅报告基线中不存在的发现 |
### 环境变量覆盖
所有关键设置都可以在运行时覆盖,而无需编辑配置文件:
| 变量 | 覆盖 |
|----------|-----------|
| `HOUND_THRESHOLD` | `threshold` |
| `HOUND_FAIL_ON` | `failOn` |
| `HOUND_MIN_CONFIDENCE` | `minConfidence` |
| `HOUND_VERBOSE` | `verbose`(真值:`1`、`true`、`yes`) |
| `HOUND_CONFIG` | 配置文件的路径 |
### `.houndignore`
在项目根目录下放置一个 `.houndignore` 文件,以便在不编辑 `.contexthoundrc.json` 的情况下添加排除模式。遵循相同的 Glob 语法;以 `#` 开头的行是注释。
### 自定义规则插件
任何导出 `Rule` 或 `Rule[]` 的 `.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 [];
},
};
```
在 `.contexthoundrc.json` 中引用它:
```
{ "plugins": ["./my-rule.js"] }
```
插件规则与内置规则一样,受 `excludeRules`、`includeRules` 和 `minConfidence` 过滤器的约束。
### 基线 / 差异模式
在初始扫描后保存基线,然后在后续扫描中仅报告新出现的发现:
```
# 保存 Baseline
hound scan --format json --out baseline
# 未来的扫描仅报告新问题
hound scan --baseline baseline.json
```
发现通过 `ruleId + file` 进行匹配 —— 行号偏移不会导致错误的新发现警告。
## 风险评分
每个发现携带按以下公式计算的**风险点数**:
```
risk_points = severity_weight × confidence_multiplier
```
点数汇总后以上限 100 封顶,并进行分类:
| 分数 | 等级 | 建议操作 |
|-------|-------|-----------------|
| 0-29 | 🟢 低 | 无需操作 |
| 30-59 | 🟡 中 | 合并前审查 |
| 60-79 | 🟠 高 | 合并前修复 |
| 80-100 | 🔴 严重 | 阻止部署 |
如果您的提示词包含明确的安全语言(输入分隔符、拒绝泄露指令、工具白名单),该提示词的风险点数将按比例减少。
## 规则
### A. 注入 (INJ)
| ID | 严重程度 | 描述 |
|----|----------|-------------|
| INJ-001 | 高 | 用户输入直接拼接到提示词中,且无分隔符 |
| INJ-002 | 中 | 缺少“将用户内容视为数据”的边界语言 |
| INJ-003 | 高 | RAG/检索到的上下文在包含时未使用不受信分隔符 |
| INJ-004 | 高 | 工具使用指令可被用户内容覆盖 |
| INJ-005 | 高 | 序列化的用户对象(`JSON.stringify`)直接插值到提示词模板中 |
| INJ-006 | 中 | 用户控制的内容中包含隐含指令动词的 HTML 注释 |
| INJ-007 | 中 | 用户输入被包裹在代码围栏分隔符中,但未先去除反引号 |
| INJ-008 | 高 | HTTP 请求数据(`req.body`、`req.query`、`req.params`)被插值到 `role: "system"` 模板字符串中 |
| INJ-009 | 严重 | HTTP 请求体被直接解析为消息数组 —— 攻击者控制角色和内容 |
| INJ-010 | 高 | 使用不受信任的输入拼接构建的纯文本角色标签记录(`User:`、`Assistant:`、`system:`) |
| INJ-011 | 高 | 浏览器 DOM 或 URL 源(`window.location`、`document.cookie`、`getElementById`)直接输入到 LLM 调用中 |
### B. 数据泄露 (EXF)
| ID | 严重程度 | 描述 |
|----|----------|-------------|
| EXF-001 | 严重 | 提示词引用了密钥、API Key 或凭据 |
| EXF-002 | 严重 | 提示词指示模型泄露系统提示词或隐藏指令 |
| EXF-003 | 高 | 提示词表明可以访问机密或私有数据 |
| EXF-004 | 高 | 提示词包含内部 URL 或基础设施主机名 |
| EXF-005 | 高 | 敏感变量(token、password、key)在输出中编码为 Base64 |
| EXF-006 | 高 | 完整的提示词或消息数组通过 `console.log` / `logger.*` 记录,且未经脱敏 |
| EXF-007 | 严重 | 实际的密钥值与“永不泄露”指令一起嵌入在提示词中 |
### C. 越狱 (JBK)
| ID | 严重程度 | 描述 |
|----|----------|-------------|
| JBK-001 | 严重 | 检测到已知的越狱短语(“ignore instructions”、“DAN”等) |
| JBK-002 | 高 | 薄弱的安全措辞(“always comply”、“no matter what”) |
| JBK-003 | 高 | 破坏安全约束的角色扮演逃逸后门 |
| JBK-004 | 高 | Agent 被指示在未经确认或人工审查的情况下行动(“proceed automatically”、“no confirmation needed”) |
| JBK-005 | 高 | 销毁证据或掩盖踪迹的指令(“delete logs”、“leave no trace”) |
| JBK-006 | 高 | 策略合法性框架与不安全操作请求相结合(“作为一名渗透测试人员,提升权限”) |
| JBK-007 | 高 | 模型身份欺骗 —— 声称是不同的 AI 模型并结合绕过安全的指令 |
| JBK-008 | 高 | 提示词压缩攻击 —— 压缩或总结系统提示词的指令 |
| JBK-009 | 高 | 嵌套指令注入 ——在“安全/无害总结/翻译”框架中的命令式指令 |
### D. 不安全工具使用 (TOOL)
| ID | 严重程度 | 描述 |
|----|----------|-------------|
| TOOL-001 | 严重 | 无界限的工具执行(“运行任何命令”、“浏览任何地方”、反引号 Shell 替换) |
| TOOL-002 | 中 | 描述工具使用时没有白名单或使用策略 |
| TOOL-003 | 高 | 提及代码执行但没有沙箱约束 |
| TOOL-004 | 严重 | 工具描述或 Schema 字段源自用户控制的变量 |
| TOOL-005 | 严重 | 工具 `name` 或端点 `url` 源自用户控制的输入(`req.body`、`req.query` 等) |
### E. 命令注入 (CMD)
检测 AI 工具周围代码中的易受攻击模式,即成功的提示词注入可能升级为完整的命令执行。参考了 Cyera Research Labs (2025) 在 Google 的 Gemini CLI 中发现的真实 CVE。
| ID | 严重程度 | 描述 |
|----|----------|-------------|
| CMD-001 | 严重 | 使用未经处理的变量插值构建 Shell 命令 —— 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 | 高 | 不完整的命令替换过滤:阻止了 `$()` 但未阻止反引号,或反之 |
| CMD-003 | 高 | 来自 `glob.sync` 或 `readdirSync` 的文件路径直接用于 Shell 命令中,未经过滤器处理 |
| CMD-004 | 严重 | Python `subprocess.run`/`subprocess.call` 在启用 `shell=True` 的情况下调用,且使用变量或 f-string 命令参数 |
| CMD-005 | 严重 | PHP 的 `shell_exec`、`system`、`passthru`、`exec` 或 `popen` 使用 `$variable` 参数调用 |
### F. RAG 投毒 (RAG)
检测检索增强生成(RAG)管道中的架构错误,这些错误允许检索或摄取的内容覆盖系统级指令。
| ID | 严重程度 | 描述 |
|----|----------|-------------|
| RAG-001 | 高 | 检索到的或外部内容被分配给消息数组中的 `role: "system"` |
| RAG-002 | 高 | 在文档摄取循环中检测到类似指令的短语(“system prompt:”、“always return”、“never redact”) |
| RAG-003 | 高 | Agent 内存存储直接从用户控制的输入写入,未经验证 |
| RAG-004 | 中 | 提示词指示模型将检索到的上下文视为最高优先级,覆盖开发者的指令 |
| RAG-005 | 中 | 无来源检索 —— 文本块插入提示词时未检查来源元数据 |
| RAG-006 | 高 | 检索内容进入提示词前未应用 ACL 或信任层级过滤器 |
### G. 编码 (ENC)
检测基于编码的注入和规避技术,其中使用 Base64 或类似编码将指令走私经过基于字符串的过滤器。
| ID | 严重程度 | 描述 |
|----|----------|-------------|
| ENC-001 | 中 | 在提示词构建附近对用户控制的变量调用 `atob`、`btoa` 或 `Buffer.from(x, 'base64')` |
| ENC-002 | 高 | 在指令关键词附近检测到隐藏的 Unicode 控制字符(零宽空格、双向覆盖) |
### H. 输出处理 (OUT)
涵盖 LLM 管道的输出端 —— 您的应用程序如何消费模型响应。不安全的消费可能将提示词注入 Payload 转化为应用程序级漏洞。
| ID | 严重程度 | 描述 |
|----|----------|-------------|
| OUT-001 | 严重 | 对 LLM 输出调用 `JSON.parse()`(JS/TS)或 `json.loads()`(Python)时未进行 Schema 验证(Zod、AJV、Joi、Pydantic、Marshmallow 等) |
| OUT-002 | 严重 | LLM 生成的 Markdown 或 HTML 在渲染时未使用 DOMPurify 或等效的过滤器 |
| OUT-003 | 严重 | LLM 输出直接用作 `exec()`、`eval()` 或 `db.query()` 的参数 |
| OUT-004 | 严重 | 使用 LLM 生成的输出作为参数调用 Python 的 `eval()` 或 `exec()` |
### I. 多模态 (VIS)
涵盖特定于视觉、音频/视频和 OCR 管道的信任边界违规。多模态输入是一种新兴的注入载体:控制图像 URL、音频文件或扫描文档的攻击者可以利用这些规则的模式将指令走私到模型中。
| ID | 严重程度 | 描述 |
|----|----------|-------------|
| VIS-001 | 严重 | 用户提供的图像 URL 或 base64 数据转发到 Vision API(gpt-4o、Claude 3、Gemini Vision),未经域名或 MIME 验证 |
| VIS-002 | 严重 | 在同时构建 Vision API 消息的文件中,使用用户控制的路径调用 `fs.readFile`/`readFileSync` —— 进入多模态输入的路径遍历 |
| VIS-003 | 高 | 音频/视频转录输出(Whisper、AssemblyAI、Deepgram 等)直接输入到提示词消息中,未经过滤器处理 —— 通过音频源进行的 RAG 投毒 |
| VIS-004 | 高 | OCR 输出(Tesseract、Google Vision)插值到 `role: "system"` 消息或系统提示词变量中 |
### J. 技能市场 (SKL) — v1.1
针对 OpenClaw `SKILL.md` 文件以及 `skills/` 目录内的任何 Markdown 文件。针对自我编写攻击、远程技能加载、注入指令、不安全命令分发、敏感路径访问、权限提升声明以及 YAML Frontmatter 中的硬编码凭据。
| ID | 严重程度 | 描述 |
|----|----------|-------------|
| SKL-001 | 严重 | 技能主体指示 Agent 编写或修改其他技能文件 —— 在 Agent 重启后持续存在的自我编写攻击 |
| SKL-002 | 严重 | 技能主体指示 Agent 从外部 URL 获取或加载技能 —— 允许攻击者在安装后更改技能行为 |
| SKL-003 | 严重 | 技能主体包含针对 Agent 核心指令的提示词注入短语(`ignore previous instructions`、`you are now unrestricted` 等) |
| SKL-004 | 高 | 技能 Frontmatter 使用 `command-dispatch: tool` 和 `command-arg-mode: raw` —— 将原始用户输入转发给工具,绕过模型安全推理 |
| SKL-005 | 高 | 技能主体引用敏感文件系统路径(`~/.ssh`、`~/.env`、`/etc/passwd`、`../../`)供 Agent 读取并可能泄露 |
| SKL-006 | 高 | 技能主体声称拥有提升的权限或指示 Agent 覆盖或禁用其他已安装的技能 |
| SKL-007 | 严重 | 在 YAML Frontmatter 中发现硬编码的凭据值(API Key、Token、Password)—— 暴露给任何接收或安装该技能的人 |
| SKL-008 | 严重 | 心跳 C2 —— 技能安排定期远程获取,以在全新安装后静默覆盖其自身指令 |
| SKL-009 | 严重 | Agent 身份否认 —— 技能指示 Agent 否认自己是 AI、声称是人类或采用欺骗性角色 |
| SKL-010 | 严重 | 反扫描器规避 —— 技能包含明确设计用于误导安全审计工具的文本 |
| SKL-011 | 严重 | SOUL.md / IDENTITY.md 持久化 —— 技能将指令写入能在卸载后幸存的 Agent 身份文件 |
| SKL-012 | 高 | 自传播蠕虫 —— 技能指示 Agent 通过 SSH 或 `curl\|bash` 传播到可达主机 |
| SKL-013 | 高 | 自主金融交易 —— 技能执行加密货币交易或持有私钥,而无需逐笔交易的用户确认 |
### K. Agentic (AGT) — v1.3
针对多步 Agent 系统特有的风险:无界限的执行循环、未经验证的内存写入以及用户输入泄露到 Agent 规划中。
| ID | 严重程度 | 描述 |
|----|----------|-------------|
| AGT-001 | 严重 | 工具调用参数接收系统提示词内容 —— 包含 `system:` 或 `instructions:` 字段内容的 `tool_call`/`function_call` 参数值 |
| AGT-002 | 高 | 无迭代或超时保护的 Agent 循环 —— Agent 配置或代码中没有 `max_iterations`、`max_steps`、`max_turns`、`timeout` 或 `recursion_limit` |
| AGT-003 | 高 | Agent 内存从未经证实的 LLM 输出写入 —— 使用原始模型响应变量调用 `memory.save()`、`memory.add()` 或 `vectorstore.upsert()` |
| AGT-004 | 高 | 计划注入 —— 用户输入直接插值到 Agent 规划、任务或目标提示词中,且无信任边界包装器 |
## 示例输出
```
=== 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
│ ├── mitigation.ts # Mitigation presence detection
│ └── index.ts # Rule registry
├── 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
```
## 局限性
- 规则使用正则表达式和结构启发法,而非完整的语义分析。可能存在误报;请务必结合上下文审查发现结果。
- 提示词不会针对模型执行;这纯粹是静态分析。
- 提取使用模式匹配而非完整的 AST。复杂的动态提示词构建可能会被遗漏。
- 对于非 JS/TS 语言(Python、Go、Rust 等),仅在检测到 LLM 库导入时才分析文件。构建提示词但无可识别导入的文件将不会被提取。
## 贡献
欢迎贡献。要添加新规则:
1. 将其添加到 `src/rules/` 中的相应文件(或为新类别创建新文件)
2. 在 `src/rules/index.ts` 中注册
3. 在 `tests/rules.test.ts` 中添加至少一个正向和一个负向测试用例
4. 运行 `npm test` 以验证所有测试是否通过
## 许可证
MIT
标签:AI供应链安全, DNS 反向解析, IPv6支持, MITM代理, Naabu, RAG安全, Red Canary, SARIF, TypeScript, 人工智能安全, 内容安全, 合规性, 安全插件, 开发安全, 敏感数据检测, 文档结构分析, 暗色界面, 私有化部署, 编码走私检测, 自动化攻击, 自动化攻击, 越狱检测, 软件 Composition Analysis, 逃逸攻击, 错误基检测, 防御规避, 静态代码分析