ppcvote/prompt-defense-audit-py
GitHub: ppcvote/prompt-defense-audit-py
针对 LLM 响应中危险 payload 的确定性正则扫描器,映射 OWASP LLM02,用于在输出到达下游系统前进行安全拦截。
Stars: 0 | Forks: 0
# prompt-defense-audit (Python)
[](https://pypi.org/project/prompt-defense-audit/)
[](https://opensource.org/licenses/MIT)
确定性的正则表达式扫描器,可在危险 payload 到达下游系统(HTML 渲染、数据库、Shell、API)**之前**检测 LLM 响应中的这些内容。映射到 **OWASP LLM02 — 不安全的输出处理 (Insecure Output Handling)**。
这是[同名 npm 包](https://www.npmjs.com/package/prompt-defense-audit)的 Python 移植版,在输出扫描器上实现了**逐字节一致性**:相同的规则、相同的匹配、相同的去重窗口、相同的风险级别阈值、相同的摘要字符串。一致性测试套件 (`tests/test_parity.py`) 确保了这两个实现的一致性。
## 为什么需要这个项目
当 LLM 输出的文本被传递到浏览器、数据库、Shell 或其他代理时,LLM 训练时的安全防护机制就不起作用了。静态输出扫描是一个确定性的、耗时不到 5ms 的关卡,你可以将其放置在模型和危险接收端之间。
- **不调用 LLM。** 纯正则表达式,完全确定性。
- **无依赖。** 仅使用标准库。
- **22 条威胁规则**,涵盖 7 个类别:XSS、SQL 注入、Shell 命令注入、路径遍历、凭证泄露、Markdown 注入、代码注入。
- **风险级别升级**,从 `safe` → `low` → `medium` → `high` → `critical`。
- **一致性测试**,对照 TypeScript 参考实现。
## 安装
```
pip install prompt-defense-audit
```
## 快速开始
```
from prompt_defense_audit import scan_output
# 包含 script tag 的 LLM 生成响应:
output = 'Here is the greeting: '
result = scan_output(output)
print(result.safe) # False
print(result.risk_level) # 'critical'
print(result.summary) # 'Found 1 threat(s): 1 critical, 0 high. Do NOT pass this output...'
for t in result.threats:
print(f" [{t.severity}] {t.id}: {t.match!r} at position {t.position}")
```
输出:
```
False
critical
Found 1 threat(s): 1 critical, 0 high. Do NOT pass this output to downstream systems without sanitization.
[critical] xss-script-tag: '' at position 21
```
## 作为中间件使用
此扫描器最有效的位置是**在 LLM 和下游接收端之间**——一个轻量级的守卫,在遇到严重威胁时会闭合阻断(安全失败),并记录中等严重性的事件。
```
from prompt_defense_audit import scan_output
def safe_render(llm_output: str) -> str:
result = scan_output(llm_output)
if result.risk_level in ("critical", "high"):
raise ValueError(f"LLM output rejected: {result.summary}")
return llm_output # safe to forward
```
对于从联邦源接收数据的 MCP 服务器(其中任何上游内容都可能是恶意构造的),在将**每个出站响应**返回给调用代理之前,请通过 `scan_output()` 进行包装处理。
## 公共 API
```
from prompt_defense_audit import scan_output, OutputScanResult, OutputThreat
result: OutputScanResult = scan_output("...")
# result.safe : bool
# result.threats : list[OutputThreat]
# result.risk_level : Literal["safe", "low", "medium", "high", "critical"]
# result.summary : str
# 每个 OutputThreat 包含:
# .id : str (稳定规则 id,例如 "xss-script-tag")
# .name : str (人类可读的规则名称)
# .severity : Literal["critical", "high", "medium", "low"]
# .match : str (匹配的 payload,截断至 100 个字符)
# .position : int (被扫描字符串中的起始索引)
# .context : str (±20 字符的窗口,其中换行符被展平)
# 两个 dataclass 均提供用于 JSON 序列化的 .to_dict()。
```
## 规则目录(7 个类别中的 22 条规则)
| 类别 | 规则 ID | 严重程度 |
|---|---|---|
| **XSS** | `xss-script-tag`, `xss-event-handler`, `xss-javascript-uri`, `xss-data-uri-html`, `xss-iframe-srcdoc`, `xss-svg-script` | critical × 3, high × 3 |
| **SQL 注入** | `sqli-destructive`, `sqli-union`, `sqli-comment-bypass` | critical × 1, high × 1, medium × 1 |
| **Shell 命令注入** | `shell-pipe-exec`, `shell-destructive`, `shell-reverse`, `shell-env-exfil` | critical × 3, high × 1 |
| **路径遍历** | `path-traversal` | high × 1 |
| **凭证泄露** | `credential-api-key`, `credential-private-key`, `credential-connection-string`, `credential-jwt` | critical × 3, high × 1 |
| **Markdown 注入** | `markdown-link-injection`, `markdown-image-tracking` | high × 1, medium × 1 |
| **代码注入** | `code-eval`, `code-python-import` | high × 1, medium × 1 |
`rm -rf /tmp/...` 被破坏性 Shell 规则明确允许,因为在教程输出中,清理 `/tmp/...` 是常见的合法操作。
## 与 TypeScript 参考实现的一致性
位于 [`ppcvote/prompt-defense-audit`](https://github.com/ppcvote/prompt-defense-audit) 的 TypeScript 参考实现是权威实现。这个 Python 移植版在涵盖所有规则、边缘情况以及聚合逻辑(去重窗口、风险级别升级、摘要文本)的 50 多个 fixture 套件上与其实现了**逐字节一致**。
一致性测试 (`tests/test_parity.py`) 在相同的 fixture 上运行这两个实现,并逐项比较结果。该契约在每次测试运行时都会得到强制执行。
如果您发现任何输入导致这两个实现出现分歧,请[提交一个 issue](https://github.com/ppcvote/prompt-defense-audit-py/issues)——这是我们需要了解的一致性错误。
## 能检测什么和不能检测什么
**能检测:** 已经到达输出缓冲区的危险 payload。扫描器不假设 payload 是*如何*到达那里的——无论是 LLM 幻觉产生的、上游文档污染了上下文,还是用户精心构造的提示词引出的。
**不能检测:**
1. 模型*是否将要*发出危险内容——扫描器是一个运行时检查,而不是静态提示词审计。有关系统提示词的部署前静态分析,请参阅 [`prompt-defense-audit` npm 包的输入扫描器](https://github.com/ppcvote/prompt-defense-audit)(目前仅支持 TypeScript)。
2. 语义威胁。扫描器基于正则表达式,无法检测例如自然语言中“给攻击者钱”这类意译的指令。
3. 下游接收端是否真的可以被利用。在输出中检测到的 `