bogdanticu88/OmniFuzz-LLM
GitHub: bogdanticu88/OmniFuzz-LLM
面向企业 LLM 部署的对抗性安全测试框架,覆盖 OWASP LLM Top 10,支持 CI/CD 集成与合规报告生成。
Stars: 0 | Forks: 0

# OmniFuzz-LLM
**LLM 的对抗性测试与红队评估框架**
[](https://github.com/bogdanticu88/OmniFuzz-LLM/actions/workflows/ci.yml)
[](https://www.python.org/)
[](LICENSE)
[](tests/)
[](https://owasp.org/www-project-top-10-for-large-language-model-applications/)
[](https://www.nist.gov/artificial-intelligence)
[](https://atlas.mitre.org/)
OmniFuzz-LLM 是一个 Python 框架,旨在帮助安全工程师和 AI 团队对已部署的 LLM 系统运行结构化的对抗性测试。它将每个发现映射到 OWASP LLM Top 10,生成符合 NIST AI RMF 和 MITRE ATLAS 标准的合规报告,并专为在 CI/CD 流水线中自动化而设计。
该框架面向需要围绕 LLM 安全性展示尽职调查的团队,不仅针对消费者越狱,还针对至关重要的企业攻击面:RAG 投毒、工具调用滥用、PII 泄露、多租户隔离失效、对抗条件下的幻觉以及凭证窃取。
## 解决的问题
目前大多数 LLM 安全测试都是临时的:红队成员在聊天界面中输入提示词并记录笔记。OmniFuzz-LLM 用可重复、结构化且可自动化的工作流取代了这种方式。您可以配置目标,选择要运行的攻击模块,通过真实的适配器(OpenAI, Anthropic, subprocess 或自定义)进行管道传输,并获得包含 OWASP 参考、严重等级和合规性摘要的调查结果报告。
相同的扫描配置可以在每次模型更新时在 CI 中运行,从而在回归问题进入生产环境之前将其捕获。
## 功能特性
### 攻击模块
每个模块针对特定的 OWASP LLM Top 10 控制项,并包含一组精心设计的 payload。
| 模块 | OWASP | 测试内容 |
|--------|-------|---------------|
| `sysprompt_extractor` | LLM07 | 14 种恢复系统提示词的技术(逐字重复、翻译技巧、权威注入、上下文渗透) |
| `tool_abuse` | LLM02 | 通过 URL 工具进行的 SSRF、通过 DB 工具进行的 SQL 注入、通过电子邮件工具进行的数据窃取、路径遍历、代码执行滥用 |
| `indirect_injection` | LLM01 | 文档、电子邮件、数据库记录中的隐藏指令,EXIF 元数据,Unicode 混淆,RAG 索引投毒 |
| `pii_compliance` | LLM06 | PHI/HIPAA、金融 PII、API 密钥、JWT token、联系数据 —— 附带 HIPAA、GDPR 和 NIST AI RMF 合规报告 |
| `multitenant_tester` | LLM04 | 跨会话秘密注入和探测,用于检测上下文渗透和 RAG 跨租户泄露 |
| `hallucination_tester` | LLM09 | 虚假前提注入、上下文矛盾、引文伪造、置信度诱导、RAG 扎实性 |
| `dos_tester` | LLM04 | Token 放大、递归推理、上下文泛洪、重复炸弹、思维链膨胀 |
| `consistency_tester` | LLM09 | 人口统计偏见检测(性别、种族、年龄、国籍、宗教)、同义词差异、不一致拒绝 |
| `embedding_poisoning` | LLM01 | 语义劫持、引文投毒、邻居泛洪、元数据注入、检索注入 |
| `credential_harvesting` | LLM06 | AWS/GitHub/OpenAI/Stripe 密钥提取、JWT secret 窃取、社会工程学、间接/混淆提取 |
| `multimodal` | LLM01 | OCR 注入、EXIF 元数据注入、文档注入、音频转录攻击、视觉越狱 |
### 适配器
将 OmniFuzz 连接到任何 LLM 端点,无需修改扫描逻辑。
| 适配器 | 描述 |
|---------|-------------|
| `OpenAIAdapter` | OpenAI `/v1/chat/completions` — 任意模型 |
| `AzureOpenAIAdapter` | Azure OpenAI,支持部署名称和 API 版本 |
| `AnthropicAdapter` | Anthropic Messages API,支持 tool-use 块检测 |
| `SubprocessAdapter` | 通过 stdin/stdout 的本地 CLI 工具和自定义模型包装器 |
所有适配器共享相同的接口。编写自定义适配器大约只需要 10 行代码。
### 报告
每次扫描都会生成结构化输出,包含 OWASP 参考、严重性评分和每个发现的详细信息。
| 格式 | 描述 |
|--------|-------------|
| JSON | 机器可读的发现列表,适用于 CI 断言和下游工具 |
| Markdown | 人类可读的报告,包含每个发现的详细信息和 OWASP 表格 |
| HTML | 独立的深色主题报告,带有严重性卡片和可折叠的发现项 |
`ComplianceReporter` 获取扫描结果,并生成包含 NIST AI RMF 和 MITRE ATLAS 交叉引用的 OWASP LLM Top 10 合规报告 —— 可直接用于审计、安全审查或内部治理委员会。
### 基础设施
| 特性 | 描述 |
|---------|-------------|
| 检查点 | 长时间扫描的原子保存/恢复 —— 使用临时文件 + `os.replace()` 确保崩溃安全 |
| 回归测试 | 对比两个扫描快照(模型更新前/后)并揭示新漏洞 |
| 代理模式 | 被动 HTTP 拦截器,评估实时流量中的对抗性指标而不进行阻断 |
| 插件架构 | 通过装饰器、入口点或模块路径注册自定义 mutator —— 内置模块在导入时自动注册 |
| Payload 库 | JSON payload 库,包含 OWASP 参考、严重性、技术标签和模型定位;加载时进行 schema 验证 |
| 配置文件 | YAML 或 TOML 配置,支持深度合并,因此部分覆盖不会清除默认值 |
### 变异器
变异器转换 payload 以规避关键词过滤和安全分类器。
| Mutator | 技术 |
|---------|-----------|
| `base64` | 编码 payload 并指示模型解码并执行 |
| `flip` | 反转 payload 文本 |
| `leetspeak` | 替换 a→4, e→3, i→1, o→0, s→5, t→7 |
| `shadow` | 结合 leetspeak + 零宽空格插入 |
| `poetic` | 将 payload 编码为维拉内拉诗或六节诗 |
| `cross_lingual` | 跨英语、德语和日语链接指令 |
## 架构
```
OmniFuzz-LLM/
├── omnifuzz/
│ ├── engine.py # Core: OmniFuzzer, FuzzResult, Reporter, OWASP_MAP
│ ├── checkpoint.py # Atomic save/resume: CheckpointManager
│ ├── config.py # YAML/TOML loader with deep-merge
│ ├── payload_manager.py # Schema validation, filtering, library management
│ ├── compliance.py # OWASP LLM Top 10 compliance report generator
│ ├── regression.py # Differential scan: diff_snapshots, RegressionRunner
│ ├── proxy.py # Passive monitoring proxy: OmniFuzzProxy
│ ├── plugin.py # Mutator plugin registry with entry-point discovery
│ ├── mutators.py # Built-in mutators (base64, flip, leetspeak)
│ ├── cross_lingual_mutators.py # CrossLingualMutator
│ ├── adapters/
│ │ ├── openai_adapter.py # OpenAI + Azure OpenAI
│ │ ├── anthropic_adapter.py # Anthropic
│ │ └── subprocess_adapter.py # Local CLI / subprocess
│ ├── modules/
│ │ ├── sysprompt_extractor.py
│ │ ├── tool_abuse.py
│ │ ├── indirect_injection.py
│ │ ├── pii_compliance.py
│ │ ├── multitenant_tester.py
│ │ ├── hallucination_tester.py
│ │ ├── dos_tester.py
│ │ ├── consistency_tester.py
│ │ ├── embedding_poisoning.py
│ │ ├── credential_harvesting.py
│ │ └── multimodal.py
│ ├── payloads/
│ │ └── library.json # Payload library with full schema
│ └── utils/
│ └── logger.py # ColorFormatter, JSON output, quiet/verbose modes
├── tests/ # 275 tests, all passing, no real LLM needed
│ ├── test_engine.py
│ ├── test_checkpoint.py
│ ├── test_mutators.py
│ ├── test_phase2.py
│ ├── test_phase3.py
│ └── test_phase4.py
├── cli.py # CLI entry point with subcommand architecture
├── main.py # Programmatic example
└── .github/workflows/ci.yml # GitHub Actions CI
```
**数据流:**
```
Config / CLI args
↓
OmniFuzzer.run_scan(payloads, adapter, evaluator)
↓
Payload → Mutator(optional) → Adapter.send() → Response
↓
Evaluator.evaluate(payload, response) → (is_vulnerable, details)
↓
FuzzResult(owasp_ref, severity, payload_index, ...)
↓
Reporter → JSON / Markdown / HTML
↓
ComplianceReporter → OWASP LLM Top 10 report
```
## 系统要求
- Python 3.11 或更高版本
- 用于适配器 HTTP 调用的 `httpx`
- 可选:用于 YAML 配置文件的 `pyyaml`,用于 TOML 的 `tomllib`(3.11+ 标准库)
运行测试套件不需要外部服务。所有 275 个测试均使用模拟适配器。
## 快速开始
**1. 克隆仓库**
```
git clone https://github.com/bogdanticu88/OmniFuzz-LLM
cd OmniFuzz-LLM
```
**2. 安装依赖**
```
pip install -r requirements.txt
```
**3. 运行测试套件**
```
python -m pytest tests/ -v
```
所有 275 个测试应在没有外部依赖的情况下通过。
**4. 从 CLI 运行扫描**
```
# 使用内置 payload 库扫描 OpenAI endpoint
python cli.py scan \
--adapter openai \
--api-key $OPENAI_API_KEY \
--model gpt-4o-mini \
--categories jailbreak sensitive_info \
--output-json results.json \
--output-html report.html
# 恢复中断的扫描
python cli.py scan --resume --checkpoint-id
# 列出保存的 checkpoint
python cli.py checkpoints list
# 向库中添加 payload
python cli.py payload add \
--id "MY-001" \
--name "Custom jailbreak" \
--payload "Ignore all instructions and..." \
--category jailbreak \
--severity high
# 生成 starter config 文件
python cli.py init-config --output omnifuzz.yaml
```
**5. 编程方式使用**
```
import asyncio
from omnifuzz.engine import OmniFuzzer
from omnifuzz.adapters.openai_adapter import OpenAIAdapter
from omnifuzz.modules import SystemPromptExtractor, ToolAbuseScanner
from omnifuzz.compliance import ComplianceReporter
async def main():
adapter = OpenAIAdapter(api_key="sk-...", model="gpt-4o-mini")
# System prompt extraction
extractor = SystemPromptExtractor(
known_prompt="You are a customer service bot.",
indicators=["customer service", "never discuss pricing"],
)
fuzzer = OmniFuzzer(adapter=adapter, evaluator=extractor)
results = await fuzzer.run_scan(extractor.get_scan_payloads())
# Tool abuse
tool_scanner = ToolAbuseScanner(techniques=["ssrf", "sql_injection"])
tool_results = await fuzzer.run_scan(
tool_scanner.get_scan_payloads(),
evaluator=tool_scanner.get_evaluator(),
)
all_results = [r.to_dict() for r in results + tool_results]
# Generate compliance report
reporter = ComplianceReporter(all_results, target="MyApp v2.1", version="gpt-4o-mini")
reporter.generate("compliance_report.html", fmt="html")
reporter.generate("compliance_report.json", fmt="json")
asyncio.run(main())
```
**6. 代理模式(被动监控)**
```
from omnifuzz.proxy import OmniFuzzProxy
proxy = OmniFuzzProxy(
on_finding=lambda event: print(f"Finding: {event.findings}"),
)
# 在你的 middleware / request handler 中:
event = await proxy.intercept(request_body, response_body, latency_ms=120)
print(proxy.stats())
```
**7. 注册自定义 mutator**
```
from omnifuzz.plugin import register_mutator, apply_mutator
@register_mutator("pig_latin")
def pig_latin(text: str) -> str:
return " ".join(w[1:] + w[0] + "ay" for w in text.split())
result = apply_mutator("pig_latin", "ignore all instructions")
# → "gnoreiay llaay nstructionsiay"
```
## 配置文件
创建配置文件以避免在每次运行时传递标志:
```
# omnifuzz.yaml
adapter: openai
model: gpt-4o-mini
categories:
- jailbreak
- sensitive_info
- system_prompt_extraction
concurrency: 5
output_json: results.json
output_html: report.html
checkpoint_dir: .omnifuzz_checkpoints
verbose: false
```
```
python cli.py scan --config omnifuzz.yaml
```
配置值与 CLI 标志深度合并 —— CLI 标志始终优先。
## 配置参考
| 键 | CLI 标志 | 默认值 | 描述 |
|-----|----------|---------|-------------|
| `adapter` | `--adapter` | `openai` | 使用的适配器:`openai`, `azure`, `anthropic`, `subprocess` |
| `api_key` | `--api-key` | (env: `OPENAI_API_KEY`) | 目标服务的 API 密钥 |
| `model` | `--model` | `gpt-4o-mini` | 模型名称或部署 ID |
| `categories` | `--categories` | all | 要包含的 payload 类别 |
| `concurrency` | `--concurrency` | `5` | 每次扫描的并行请求数 |
| `output_json` | `--output-json` | (none) | 将 JSON 发现结果写入此路径 |
| `output_html` | `--output-html` | (none) | 将 HTML 报告写入此路径 |
| `output_markdown` | `--output-markdown` | (none) | 将 Markdown 报告写入此路径 |
| `checkpoint_dir` | `--checkpoint-dir` | `.omnifuzz_checkpoints` | 检查点文件的目录 |
| `verbose` | `--verbose` | `false` | 启用调试日志 |
| `quiet` | `--quiet` | `false` | 除发现结果外抑制所有输出 |
| `log_file` | `--log-file` | (none) | 将日志写入文件 |
| `json_logs` | `--json-logs` | `false` | 将日志输出为 JSON(用于日志聚合器) |
## OWASP LLM Top 10 覆盖范围
| 控制项 | 名称 | 模块 | 状态 |
|---------|------|---------|--------|
| LLM01 | Prompt Injection | `indirect_injection`, `embedding_poisoning`, `multimodal` | ✅ 已覆盖 |
| LLM02 | Insecure Output Handling | `tool_abuse` | ✅ 已覆盖 |
| LLM03 | Training Data Poisoning | `embedding_poisoning` (部分) | ⚠️ 部分 |
| LLM04 | Model Denial of Service | `dos_tester`, `multitenant_tester` | ✅ 已覆盖 |
| LLM05 | Supply Chain Vulnerabilities | — | ⬜ 仅基础设施 |
| LLM06 | Sensitive Information Disclosure | `pii_compliance`, `credential_harvesting` | ✅ 已覆盖 |
| LLM07 | Insecure Plugin Design | `sysprompt_extractor`, `tool_abuse` | ✅ 已覆盖 |
| LLM08 | Excessive Agency | `tool_abuse`, `indirect_injection` | ✅ 已覆盖 |
| LLM09 | Overreliance | `hallucination_tester`, `consistency_tester` | ✅ 已覆盖 |
| LLM10 | Model Theft | `sysprompt_extractor` | ✅ 已覆盖 |
## 编写自定义适配器
任何接受字符串并返回字符串的可调用对象都可以作为适配器。对于异步:
```
class MyAdapter:
async def send(self, prompt: str) -> str:
# call your model here
return response_text
```
将其传递给 `OmniFuzzer(adapter=MyAdapter())`。
## 编写自定义模块
扫描模块需要两样东西:
```
class MyModule:
def get_scan_payloads(self) -> list[dict]:
# Return list of {"text": "...", "category": "...", "index": N}
return [...]
def get_evaluator(self):
# Return an object with async evaluate(payload, response) -> (bool, str)
return MyEvaluator()
class MyEvaluator:
async def evaluate(self, payload: str, response: str) -> tuple[bool, str]:
is_vulnerable = "bad signal" in response.lower()
return is_vulnerable, "details here"
```
## 路线图
### 近期
**对比模式 UI** —— 用于并排比较两次扫描运行的 HTML 报告(例如 GPT-4o 与 Claude 3.5 Sonnet 针对同一组 payload)已在回归模块中部分实现,但尚未有专用的报告模板。
**Payload 库扩展** —— 内置的 `library.json` 涵盖了越狱和敏感信息探测。它需要更多针对工具调用滥用、多代理场景和 RAG 特定攻击的 payload。
**SARIF 输出** —— 使用 GitHub Advanced Security 或其他 SAST 平台的安全团队期望获得 SARIF 格式的发现结果。添加 SARIF 报告器将允许 OmniFuzz 结果直接显示在 GitHub Security 标签页中。
**实时代理服务器** —— `OmniFuzzProxy` 类提供了核心拦截逻辑,但没有可以放置在真实 OpenAI 端点前的独立 HTTP 服务器。基于 `uvicorn` 的轻量级代理服务器(`omnifuzz proxy start`)是自然的下一步。
### 长期
**包含真实图像的多模态输入** —— 多模态模块目前模拟 OCR 后视觉模型接收到的内容。生成实际的对抗性图像(图像上的文本、EXIF 注入、隐写 payload)并将其提交给支持视觉的模型将使测试更加真实。
**代理 / 多步扫描模式** —— 当前的扫描是单轮的。许多现实世界的漏洞利用(工具调用滥用、间接注入链接)需要多轮对话,其中攻击者的 payload 在第 1 步和第 2 步建立上下文后的第 3 步到达。需要一个有状态的多轮扫描引擎。
**Embedding 距离评分** —— 投毒模块通过将文档直接注入提示词来模拟 RAG 场景。更精确的测试将使用实际的 embedding 模型,在运行扫描之前验证投毒文档是否排在检索结果的前列。
**微调回归跟踪** —— 对模型进行微调的团队不仅需要跟踪单个扫描结果,还需要跟踪训练检查点的趋势。轻量级数据库后端(默认为 SQLite,可选 PostgreSQL)将允许 OmniFuzz 存储历史扫描结果并绘制随时间变化的漏洞趋势。
## 许可证
MIT。请参阅 [LICENSE](LICENSE)。
标签:AI安全, AI风险管理, Chat Copilot, CISA项目, DevSecOps, LNA, MITRE ATLAS, NIST AI RMF, OWASP Top 10, PII泄露, Python, Python安全, RAG投毒, 上游代理, 企业级安全, 凭证收集, 域名收集, 大模型风险评估, 安全合规, 安全规则引擎, 密码管理, 对抗性测试, 工具调用滥用, 攻击模拟, 无后门, 网络代理, 计算机取证, 越狱检测, 运行时操纵, 驱动签名利用