项目:离线 Agent 威胁评审
你要完成什么
对一个“读取一封邮件并生成草稿,绝不自动发送”的 Agent 建立严格场景契约,并用确定性 Python 规则找出从不可信邮件到工具、身份、数据出站、供应链和运营控制的风险。项目离线运行,不调用模型、连接器或网络,不需要密钥。
这不是漏洞扫描器或渗透测试。它训练的是一条可复用工程链:
用途/非目标 → 资产与边界 → 能力/身份/依赖 → 控制契约
→ 确定性发现 → PASS/REVIEW/BLOCK → 回归测试文件说明
| 文件 | 用途 |
|---|---|
examples/threat_review.py | 严格 JSON 解析、契约校验、11 条教学规则、决策与 CLI |
examples/agent_scenario_vulnerable.json | 故意暴露过多能力的场景,预期 BLOCK |
examples/agent_scenario_hardened.json | 最小权限只读场景,预期 PASS |
examples/agent_scenario_contract_error.json | 含未知字段,预期契约错误 |
examples/test_threat_review.py | 合同、规则、指纹、CLI 与自测的回归测试 |
输入显式声明资产分类、信任边界、非权威来源、身份 scope/有效期、工具执行身份/副作用/具体 endpoint 与资源、数据出站、依赖摘要、审批/沙箱/记忆流和风险政策。严格契约拒绝重复 JSON key、NaN、未知字段、悬空引用、矛盾的 mode/effect、宽泛目的地和未覆盖严重度,避免“脏输入被静默解释”。
运行环境
- Windows 11 + PowerShell 7;
- 当前稳定 Python 3;
- 只使用标准库,不安装依赖。
从本笔记所在目录运行:
Set-Location '.\examples' # 进入场景、实现和测试所在目录,以下相对路径才可直接运行。
# 漏洞场景:退出码 1,action=BLOCK
python -B .\threat_review.py --scenario .\agent_scenario_vulnerable.json # 运行故意宽权限的场景,验证其稳定得到 BLOCK。
# 加固场景:退出码 0,action=PASS
python -B .\threat_review.py --scenario .\agent_scenario_hardened.json # 运行最小权限的加固场景,验证其得到 PASS。
# 输入契约错误:退出码 2
python -B .\threat_review.py --scenario .\agent_scenario_contract_error.json # 用未知字段 fixture 验证输入契约 fail-closed。
# 内置冒烟检查
python -B .\threat_review.py --self-test # 执行脚本内置的快速自检路径。
# 80 项测试;再用 -O 和 warnings-as-errors 验证测试不依赖 assert/警告
python -B -m unittest discover -s . -p 'test_*.py' -v # 正常模式下发现并详细运行全部测试。
python -B -O -m unittest discover -s . -p 'test_*.py' # 用 -O 验证生产规则不依赖 bare assert。
python -B -W error -m unittest discover -s . -p 'test_*.py' # 将 warning 变成失败,检查更严格的运行条件。PowerShell 中退出码在 $LASTEXITCODE。这里 BLOCK/REVIEW 返回 1 是预期业务决策,不等于程序崩溃。
阅读实现
1. 严格契约
load_json 拒绝重复 key 和非标准常量;validate_scenario 对每层做精确字段、类型、枚举、唯一 ID 与引用完整性检查,并返回深拷贝。契约错误统一退出 2。
2. 11 条教学发现
规则覆盖间接注入到副作用工具、非必要功能、共享/长期/过宽身份、弱审批、目的地缺少约束、敏感数据无出站验证、依赖未固定/未验证、沙箱不足、工具参数未验证、记忆投毒以及审计/限流/紧急停用缺失。
每条发现都含资产、攻击路径、影响、建议控制、负责人和验证方法。结果按严重度与 ID 稳定排序,便于 diff 和门禁。
这 11 条规则不是 OWASP Agentic Top 10 的自动合规映射。它们没有完整验证 Agent 间消息身份/完整性、跨 Agent 级联、人的信任校准或自主偏离/rogue 行为;多 Agent 项目应把这些风险另建场景、终态断言与演练,而不是用本项目的 PASS 代替。可将协作侧的负向合同接到 身份、授权与跨边界信任,再把两类结果共同放入发布门。
3. 决策与证据指纹
场景内冻结哪些严重度 BLOCK、哪些需要 REVIEW;无触发项才 PASS。报告用场景与发现的规范 JSON 计算 SHA-256 指纹,帮助确认比较的是同一证据,但指纹不是数字签名,也不能证明输入真实。
验收任务
基础验收
- 漏洞场景产生
AS-001到AS-011,动作为BLOCK。 - 加固场景无发现,动作为
PASS。 - 契约错误场景返回退出码 2,不产生看似有效报告。
- 三种测试模式全部通过且不生成缓存。
理解验收
逐条解释为什么漏洞场景触发 11 项规则,并把每项映射到本库相应课程。特别说明:为什么删除 send_mail 比提示模型“不要发送”更强;为什么工具 schema 仍需授权;为什么 PASS 不能声称系统已安全。
扩展任务
复制加固场景,构造一个只把依赖 pinned 改为 false 的场景,确认得到 REVIEW 和 AS-007。再设计自己的“共享盘转工单”JSON;先写预期发现和决策,再运行。若要新增字段,先改契约和失败测试,不要让未知字段静默通过。
自测题
- 为什么外部内容、模型输出和工具返回都应视为不可信?
required_for_purpose如何帮助发现功能过多?它为什么不能代替人工威胁建模?- 同一个身份同时有
mail.read与mail.send的爆炸半径是什么? - 为什么批准要绑定规范化参数与状态版本?
- 报告指纹能证明什么,不能证明什么?
- 规则全部未触发时,还缺哪些真实验证?
参考答案要点:确定性规则只能检查声明的有限契约;没有执行真实模型、身份提供方、工具、沙箱或网络,也没有验证 JSON 声明是否符合部署。因此 PASS 只表示“该输入未触发教学规则”。
进一步学习
- 回看 资产、信任边界与威胁建模。
- 把发现转为 评测体系 中的安全回归与发布门。
- 将拒绝、审批与紧急停用事件接入 运行监控。
参考资料
- OWASP LLM01:2025 Prompt Injection(获取日期:2026-07-22)
- OWASP Top 10 for Agentic Applications(2025 年 12 月发布;获取日期:2026-07-22)
- MITRE ATLAS(获取日期:2026-07-22)