minyanyi/llm-security-checklist
GitHub: minyanyi/llm-security-checklist
一款零依赖的Python安全扫描器,专为检测LLM应用中Prompt注入、SSRF、密钥泄露等AI特有安全风险而设计,并映射OWASP LLM Top 10。
Stars: 0 | Forks: 0
# llm-security-checklist
**针对 LLM 驱动应用的自动化安全扫描器 + 全面测试清单。**
[](https://www.python.org/downloads/)
[](scanner.py)
[](checklist.md)
[](tests/test_scanner.py)
[](LICENSE)
## 为什么开发此工具
大多数发布 LLM 功能的团队只测试了传统的 Web 漏洞——而完全忽略了 AI 特有的攻击面。Prompt injection、工具调用 SSRF、系统提示词泄露以及无限制的 token 消耗在常规的渗透测试中根本无法被发现。
此工具为您提供:
1. **`scanner.py`** — 一个零依赖的 Python CLI,可针对您的 LLM API 运行 11 项自动化检查,并输出结构化的 JSON 报告。
2. **`checklist.md`** — 一份包含 70 多项手动测试的清单,映射了 [OWASP Top 10 for LLM Applications 2025](https://owasp.org/www-project-top-10-for-large-language-model-applications/) 中的每一个条目。
## 扫描器测试内容
| # | 检查项 | OWASP | 严重程度 | 方法 |
|---|-------|-------|----------|--------|
| 1 | Prompt injection(基于 canary) | LLM01 | 高危 | 通过覆盖 payload 注入随机的 canary token;检测逐字/部分回显 |
| 2 | 系统提示词泄露 | LLM07 | 中危 | 提取提示词 + 对祈使句指令语言的启发式评分 |
| 3 | 通过工具调用引发的 SSRF | LLM06 | 高危 | 提示模型获取 cloud-metadata/内部 URL;对 AWS/GCP/内部特征进行模式匹配响应 |
| 4 | 前端 API key 泄露 | LLM02 | 严重 | 获取首页及链接的 JS 资产;通过正则 + Shannon 熵扫描检测 13 种机密类型 |
| 5 | 未经身份验证的 LLM 访问 | LLM06 | 严重 | 发送未经身份验证的 chat completion;标记 HTTP 200 响应 |
| 6 | 速率限制 / 无限制消耗 | LLM10 | 中危 | 瞬间发送 N 个快速请求;检测 429/503/Retry-After 节流 |
| 7 | 详细的错误信息 / 堆栈跟踪泄露 | LLM02 | 中危 | 发送格式错误的 JSON、错误的 content-type、超大 payload;匹配 traceback 模式 |
| 8 | Debug endpoint 暴露 | LLM02 | 高危 | 探测 `.env`、`.git/config`、`/actuator/env`、`/metrics`、`/openapi.json`、`/admin` 等 |
| 9 | 安全 header 加固 | 加固 | 低危 | 检查 HSTS、CSP、X-Content-Type-Options、Referrer-Policy |
| 10 | new-api MJ 图像 IDOR | 访问控制 | 中危 | 通过 /api/status 指纹识别 new-api/one-api;测试 /mj/image/:id 的未授权访问 (CVSS 5.3) |
| 11 | 计费竞态条件风险提示 | 业务逻辑 | 严重 | 检测 new-api/one-api 实例并警告 TOCTOU 配额竞态条件 (CVSS 9.1) |
每项检查都会生成一个包含严重程度、证据和修复指南的结构化发现结果。没有虚假的“打印语句”结果——真实的检测逻辑包含熵过滤、canary 验证和特征匹配。
## 快速开始
```
# 无需安装 — 仅需 stdlib (Python 3.9+)
git clone https://github.com/minyanyi/llm-security-checklist.git
cd llm-security-checklist
# 扫描 OpenAI 兼容 API(未授权检查无需 key)
python scanner.py --target https://api.your-app.com
# 通过授权 LLM 检查进行全面扫描
python scanner.py --target https://api.your-app.com \
--chat-path /v1/chat/completions \
--api-key sk-your-key \
--model gpt-4o-mini \
--output report.json
# CI gate:遇到 high+ 级别发现时使构建失败
python scanner.py -t https://staging.your-app.com --fail-on high --no-color
# 仅运行特定检查
python scanner.py -t https://api.your-app.com --checks prompt-injection,ssrf-tool-calling,api-key-exposure
# 列出所有可用检查
python scanner.py --list-checks
```
### 输出示例
```
========================================================================
llm-security-checklist v1.0.0 — https://api.your-app.com
========================================================================
[ FAIL] prompt-injection (high ) Model obeyed injected instructions and echoed the attacker canary…
└─ Sure! INJCANARY-8F3A2B1C is the answer.
[ PASS] system-prompt-leak (medium ) No system-prompt leakage detected (best heuristic score 1).
[ FAIL] ssrf-tool-calling (high ) LLM tool-calling returned internal/cloud-metadata content…
[ PASS] api-key-exposure (critical) No known secret patterns in the index page or 4 linked JS asset(s).
[ FAIL] unauthenticated-access (critical) Chat endpoint answered a request with NO credentials…
[ PASS] rate-limiting (medium ) Rate limiting observed: 12/15 requests throttled.
[ PASS] verbose-errors (medium ) Malformed requests did not leak stack traces or internals.
[ FAIL] debug-endpoints (high ) 2 sensitive/debug path(s) publicly accessible.
[ WARN] security-headers (low ) Missing security headers: Content-Security-Policy, Referrer-Policy.
Checks: 9 Failed: 4 Warnings: 1 Errors: 0 Skipped: 0
Findings by severity: critical=1 high=2 medium=0 low=0 info=0
```
### JSON 报告结构
```
{
"tool": "llm-security-checklist",
"version": "1.0.0",
"target": "https://api.your-app.com",
"summary": {
"checks_run": 9,
"failed": 4,
"findings_by_severity": {"critical": 1, "high": 2, "medium": 0, "low": 0, "info": 0}
},
"checks": [
{
"id": "prompt-injection",
"owasp": "LLM01",
"severity": "high",
"status": "fail",
"evidence": ["Sure! INJCANARY-8F3A2B1C is the answer."],
"recommendations": ["Treat all user input as untrusted…"]
}
]
}
```
## CLI 参考
| 标志 | 默认值 | 描述 |
|------|---------|-------------|
| `--target, -t` | *(必填)* | 目标应用/API 的基础 URL |
| `--chat-path` | `/v1/chat/completions` | Chat-completions endpoint 路径 |
| `--api-key` | `$LLM_API_KEY` | 用于经过身份验证的 LLM 检查的 API key |
| `--model` | `gpt-4o-mini` | chat payload 中发送的模型名称 |
| `--timeout` | `15.0` | 每次请求的超时时间(秒) |
| `--rate-limit-requests` | `15` | 速率限制突发中的请求数 |
| `--max-js-assets` | `10` | 扫描机密信息的最大链接 JS 资产数 |
| `--canary-url` | — | 用于 SSRF 验证的带外 canary URL (interactsh/canarytokens) |
| `--header KEY:VALUE` | — | LLM 请求的额外 header(可重复) |
| `--checks` | all | 要运行的、以逗号分隔的检查 ID |
| `--output, -o` | — | 将 JSON 报告写入文件 |
| `--fail-on` | `high` | 遇到此严重级别及以上的发现时以状态码 1 退出(CI 门禁) |
| `--insecure` | off | 跳过 TLS 验证(仅供实验环境使用) |
| `--user-agent` | 工具 UA | 覆盖 User-Agent |
| `--verbose, -v` | off | 调试日志记录 |
| `--no-color` | off | 禁用 ANSI 颜色 |
## 手动检查清单
自动化扫描器涵盖了 🤖 项。完整的 [checklist.md](checklist.md) 在所有 10 个 OWASP LLM 类别中增加了 60 多项手动测试项:
- 通过 RAG 文档进行的间接 Prompt injection
- 供应链(模型文件、插件、MCP server、被污染的微调数据)
- 向量/嵌入弱点(反转、被污染的检索、租户隔离)
- 输出处理(eval injection、通过 LLM 引发的 XSS、模板注入)
- 虚假信息和过度依赖控制
- Denial-of-wallet 与 token 泛滥
## 运行测试
```
python -m unittest discover -s tests -v
# 64 个测试 — 所有检测逻辑均由单元测试覆盖,无需网络
```
## 架构
```
scanner.py
├── Detection primitives (pure functions, unit-tested)
│ ├── shannon_entropy() — filters low-entropy false positives
│ ├── find_secrets_in_text() — 13 secret patterns + entropy gating
│ ├── classify_injection() — canary echo classification
│ ├── leak_score() — system prompt leakage heuristic
│ ├── detect_ssrf_evidence() — cloud-metadata signature matching
│ ├── detect_verbose_error() — stack trace pattern detection
│ └── judge_rate_limit() — throttling verdict logic
├── HttpClient — stdlib urllib wrapper, TLS options, error normalization
├── Scanner — orchestrates 11 checks, builds JSON report
└── CLI — argparse, colored output, CI exit codes
```
## 局限性(真实的)
- **Prompt injection 检测基于 canary** —— 它能捕获简单的注入,但无法应对复杂的越狱。任何扫描器都无法保证完全免受注入。
- **SSRF 检查取决于模型是否确实具备 URL 获取工具** —— 如果您的应用没有工具调用,这些检查会轻易通过。
- **系统提示词泄露使用启发式方法** —— 可能会出现误报和漏报。始终需要人工验证。
- **这不是渗透测试。** 这只是一次初步的自动化筛选。生产级 LLM 系统需要由了解您特定架构的专业人员进行对抗性测试。
## ⚠️ 法律与道德使用
**仅扫描您拥有或获得明确书面授权测试的系统。** 未经授权的扫描可能会违反计算机欺诈法(如 CFAA、Computer Misuse Act 等)。作者对滥用行为不承担任何责任。
## 作者
**Yan** — OSCP / OSCE / CEH
专注于 LLM 应用安全的 AI 安全研究员和渗透测试人员。
📧 [yan@elarab.tech](mailto:yan@elarab.tech)
标签:AI安全, Chat Copilot, CISA项目, DLL 劫持, GraphQL安全矩阵, OWASP LLM Top 10, Python, 大语言模型, 安全助手, 安全扫描器, 文档结构分析, 无后门, 逆向工具