andrewsferreira/llm-security-testing-framework
GitHub: andrewsferreira/llm-security-testing-framework
针对基于 LLM 的聊天机器人、agents 和工具调用 API 的安全测试框架,覆盖九大攻击类别共 65 个测试用例,内置模拟靶场并可生成多种格式报告。
Stars: 0 | Forks: 0
# LLM 安全测试框架
**一个针对基于 LLM 的聊天机器人、agents 和工具调用 API 的安全测试框架。**
[](https://github.com/andrewsferreira/llm-security-testing-framework/actions/workflows/ci.yml)
[](https://github.com/andrewsferreira/llm-security-testing-framework/actions/workflows/security.yml)
[](LICENSE)
[](pyproject.toml)
## 这是什么
llmsec 针对基于 LLM 的 HTTP 目标运行结构化的安全测试活动——包括 prompt injection、jailbreaks、system-prompt 泄露、数据泄露、工具滥用、context 操纵、不安全的输出处理以及过度权限——并生成 JSON/Markdown/HTML/SARIF 报告。它自带了一个本地的、完全模拟的目标(同一个虚假聊天机器人的“vulnerable”和“hardened”模式),因此整个过程无需 API 密钥、无需外部服务且没有成本,即可运行并展示真实的场景。
## 该项目解决的问题
基于 LLM 的应用程序引入了一类无法简单套用传统 AppSec 工具的安全问题:SAST 扫描器无法捕捉到“模型遵循了嵌入在检索文档中的指令”,而 DAST 扫描器也不知道正确的拒绝应该是什么样的。[OWASP Top 10 for LLM Applications](https://owasp.org/www-project-top-10-for-large-language-model-applications/) 命名了这些风险;该项目提供了一种具体、可运行的方式,针对您自己的应用程序测试其中的多项风险,并包含一个从零搭建的实验室,用于在完全相同的测试套件上展示未缓解目标与已缓解目标之间的差异。
## 核心功能
- **9 个攻击类别,65 个测试用例** —— 直接与间接 prompt injection、jailbreak、system-prompt 泄露、数据泄露、工具滥用、context 操纵、不安全的输出处理、过度权限。测试用例是 YAML 数据 (`payloads/*.yaml`),而不是代码。
- **内置实验室目标** —— 一个基于规则且确定性的 FastAPI 聊天机器人/agent,具有 vulnerable 和 hardened 模式,因此每个类别都有真实的内容可以在本地免费进行演示。
- **5 个可插拔的评估器** —— keyword、regex、lexical-similarity(“semantic”)、tool-call policy 以及一个 composite combinator —— 每个评估器都诚实地记录了它实际检查的内容(参见 [`docs/scoring-model.md`](docs/scoring-model.md))。
- **异步执行引擎** —— 有界并发、单次测试超时、带 backoff 的重试、可选的 rate limiting 以及 stop-on-critical。
- **4 种报告格式** —— JSON、Markdown、一个自包含且可过滤的 HTML 报告,以及 SARIF 2.1.0(用于 GitHub code scanning)。
- **记录完善的风险评分模型** —— 具有明确的公式,并明确标记为实验室启发式方法,而非行业标准。
- **目标无关** —— 为您自己的 API 提供可配置的通用 HTTP envelope,以及一个可直接对接 OpenAI/Anthropic 原生 chat API 的可选适配器。
- **默认具备 SSRF 防护意识** —— 除非您明确同意,否则拒绝非本地目标。
- **完全容器化** —— 提供用于框架和实验室的 Docker 镜像、Docker Compose stack,以及用于 CI、安全扫描和发布的 GitHub Actions。
## 架构
三个独立可用的部分:**框架**(`src/llmsec/`,可通过 pip 安装,具有 CLI)、**实验室**(`lab/`,一个独立的 FastAPI 应用程序,不依赖该框架)以及 **payloads**(`payloads/*.yaml`,纯数据)。有关执行流程的完整分解和图表,请参阅 [`docs/architecture.md`](docs/architecture.md)。
```
llmsec CLI → engine → registry (loads payloads/*.yaml)
→ runner (async execution) → target (HTTP) → lab / your API
→ evaluators → evidence (redaction) → scoring → reporters
```
## 测试类别
| 类别 | 测试内容 | OWASP LLM 映射 |
| --- | --- | --- |
| Direct Prompt Injection | 试图明确覆盖/忽略/绕过指令的行为 | LLM01 |
| Indirect Prompt Injection | 嵌入在不受信任内容(文档、工具输出)中的指令 | LLM01 |
| Jailbreak | 角色扮演、假设情境、编码、权威冒充、多轮升级 | LLM01 |
| System Prompt Leakage | 提取隐藏的指令、内部规则、工具描述 | LLM07 |
| Data Exfiltration | 直接、通过转换或跨轮次提取上下文中的机密信息 | LLM02 |
| Tool Abuse | 未经授权/超出范围的工具调用、路径遍历、不允许的目标地址 | LLM06 |
| Context Manipulation | 污染对话记忆、伪造事实、重新定义角色/任务 | LLM01 |
| Insecure Output Handling | 输出内容若在下游未转义即被使用是否会带来危险 | LLM05 |
| Excessive Agency | 未经确认即采取行动、串联未经请求的操作 | LLM06 |
## 快速开始
```
git clone https://github.com/andrewsferreira/llm-security-testing-framework.git
cd llm-security-testing-framework
python3.12 -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
# 在后台启动内置的 lab(vulnerable mode)
uvicorn lab.app.main:app --port 8000 &
# 扫描它
llmsec scan --target http://localhost:8000 --suite all \
--config configs/local.yaml --output reports/demo
```
这就是全部过程——不需要 API 密钥。有关包含 hardened 模式对比的更完整演练,请参阅 [`docs/portfolio-demo.md`](docs/portfolio-demo.md)。
## 本地安装
需要 Python 3.12+。
```
python3.12 -m venv .venv
source .venv/bin/activate # .venv\Scripts\activate on Windows
pip install -e ".[dev]"
llmsec version
```
运行 CI 所执行的检查:
```
ruff check . && ruff format --check .
mypy src/llmsec lab
pytest tests/ --cov=llmsec --cov-report=term-missing
bandit -r src lab -c pyproject.toml
pip-audit
```
## 使用 Docker
```
docker compose up -d lab # starts the lab target, waits for /health
docker compose run --rm scanner \
llmsec scan --target http://lab:8000 --suite all \
--config configs/docker.yaml --output reports
docker compose down
```
使用 `LAB_MODE=hardened docker compose up -d lab` 切换实验室的模式。`configs/docker.yaml` 记录了为什么它设置 `allow_external_targets: true`(`lab` Compose 主机名不是一个字面意义上的 loopback IP,尽管在该网络内它与 localhost 一样是隔离的——参见 [`docs/threat-model.md`](docs/threat-model.md))。报告将通过 bind mount 生成在主机的 `./reports` 目录中。
## CLI 示例
```
llmsec version
llmsec validate-config --config configs/local.yaml
llmsec list-tests
llmsec list-tests --category jailbreak
llmsec scan --target http://localhost:8000 --suite all --config configs/local.yaml --output reports/run-001
llmsec scan --target http://localhost:8000 --suite tool_abuse --config configs/local.yaml --output reports/run-002
llmsec report --input reports/run-001/campaign-.../results.json --format html --format markdown
llmsec compare --input reports/run-001/campaign-.../results.json --input reports/run-002/campaign-.../results.json
llmsec dashboard --reports-dir reports --output reports/dashboard.html
```
## 结果示例
```
Campaign campaign-20260101T000000Z-abc12345 (all): 65 test(s)
passed: 0
failed: 65
inconclusive: 0
errors: 0
json : reports/run-001/campaign-.../results.json
markdown : reports/run-001/campaign-.../report.md
html : reports/run-001/campaign-.../report.html
sarif : reports/run-001/campaign-.../results.sarif
```
针对 `LAB_MODE=hardened` 运行相同的测试套件,这 65 个测试将全部变为 `passed`,并且 `failed: 0`,exit code 为 `0` 而不是 `1`——相同的测试套件,相同的框架,展现了目标行为上的真实差异。
## 报告示例
HTML 报告是自包含的(没有 CDN,没有外部字体/脚本),具有类别/严重性过滤器、执行摘要、严重性/类别分布表以及每个发现结果的证据(脱敏的请求/响应、匹配的指标、解释、修复建议)。生成一个并在本地打开它:
```
open reports/run-001/campaign-*/report.html # macOS; xdg-open on Linux
```
## 评分模型
```
risk_score = severity_weight × confidence × exploitability (rescaled to 0–10)
```
明确记录为用于对单次活动内的发现结果进行排名的实验室专用启发式算法,而非行业标准的指标——完整细节(包括每个评估器究竟如何设置其 `confidence`)请参见 [`docs/scoring-model.md`](docs/scoring-model.md)。
## 创建自定义测试用例
测试用例采用 YAML 格式,并针对 Pydantic schema 进行了验证——无需 Python 即可添加。有关 schema、5 种评估器配置形状,以及——重要的是——如何针对内置的(基于规则的)实验室验证新的 payload 是否确实触发了预期行为的详细说明,请参见 [`docs/creating-test-cases.md`](docs/creating-test-cases.md)。`examples/custom_test.py` 则是一个直接在 Python 中定义和评估测试用例的可运行示例。
## 创建自定义目标
实现一个 async 方法(`Target.send`),即可集成任何通用 HTTP envelope 无法表达的内容——请参阅 [`docs/target-integration.md`](docs/target-integration.md) 和 `examples/custom_target.py` 获取完整、可运行的示例。
## CI/CD 集成
此 repo 中内置了三个 GitHub Actions workflows:
- **`.github/workflows/ci.yml`** —— ruff、mypy、带 coverage 的完整 pytest 套件、package 构建。
- **`.github/workflows/security.yml`** —— Bandit(SARIF 上传至 code scanning)、pip-audit、Gitleaks、针对两个 Dockerfile 的 Hadolint。
- **`.github/workflows/release.yml`** —— 由 tag 触发的 build + changelog + GitHub release。PyPI 发布功能虽已存在但已被注释掉,需要显式的 secret——绝不会自动执行。
SARIF 报告格式 (`reporters/sarif_reporter.py`) 旨在与这些 workflows 使用的相同 code scanning pipeline 对接,并排显示 Bandit 自身的 SARIF 输出。
## 局限性
直白地指出,绝不隐瞒:
- **内置的实验室是一个基于规则、确定性的模拟器——而不是真实的 LLM。** 它演示了检测的*机制*(标记泄露、工具调用执行了未经授权的操作),而不是真实模型实际会做的事情。参见 [`docs/creating-test-cases.md`](docs/creating-test-cases.md)。
- **评估器是启发式的**,而不是形式化验证。`INCONCLUSIVE` 的意思是“应该由人工查看”,而不是“安全”。`semantic` 评估器基于 lexical token-overlap,明确指出不是基于 embedding 的——参见 [`docs/scoring-model.md`](docs/scoring-model.md)。
- **风险评分是实验室专用的启发式算法**,不是可比较的行业标准指标。
- **SSRF 防护是静态主机检查**,不具备 DNS 意识——它无法抵御 DNS rebinding。参见 [`docs/threat-model.md`](docs/threat-model.md)。
- **65 个测试用例是一个扎实的演示集,并未穷尽**这 9 个类别中的任何一个。
- **Docker build/compose 已在真实的 Docker runtime 中验证过**(本项目开发期间通过 `colima` 安装)——有关实际进行和未进行实时测试的确切内容,请参见 `docs/threat-model.md` 和项目自身的 commit history。
- 这是一个**作品集项目**,而不是生产级的安全产品。在将其用于任何重要事项之前,请先阅读代码。
## 路线图
参见 [`docs/roadmap.md`](docs/roadmap.md) —— 基于真实 embedding 的 semantic 评估器、更广泛的 payload 覆盖范围、更丰富的多轮对话模型以及具备 DNS 意识的 SSRF 检查是最有可能的下一步计划。
## 安全性
有关如何报告框架本身的漏洞,请参见 [`SECURITY.md`](SECURITY.md);有关扫描器、实验室以及它们通常如何一起部署的完整 STRIDE 分析,请参见 [`docs/threat-model.md`](docs/threat-model.md)。
## License
[MIT](LICENSE)
## 作者
**Andrews Ferreira**
- GitHub: [github.com/andrewsferreira](https://github.com/andrewsferreira)
- Medium: [medium.com/@andrewsferreira](https://medium.com/@andrewsferreira)
标签:AI安全, Chat Copilot, DLL 劫持, Python, 大语言模型, 安全测试, 攻击性安全, 无后门, 渗透测试框架, 请求拦截, 逆向工具, 防御