全程无需任何 API key;两个脚本都是纯 Python 标准库的确定性模拟,在任何 Python 3.10+ 环境可跑。 实验目标:亲手「打穿」一个只有 prompt 禁令的系统,再亲手把它防住——把 README 第 2、3、4 节变成肌肉记忆。
🎯 学习重点:观察“内容进入模型”与“动作被网关放行”是两个独立控制点。
对应示例:../examples/indirect_injection_demo.py
injection_screen() 的筛查规则、gateway_check() 的白名单逻辑。 cd 11-security/examples
python3 indirect_injection_demo.py
观察场景 A/B/C 的差异:无防御时注入直达执行层;仅 prompt 禁令时照样发出高危调用;分层防御下载荷在哪一层被拦。
INJECTION_PATTERNS,重跑确认拦截。体会「筛查要持续监控、持续迭代」的运维含义。render_tool_result() 的 JSON 编码去掉、直接拼接正文,哪个防御层受影响?为什么官方强调 JSON 转义提供了「无歧义定界符」?🎯 学习重点:用参数白名单与资源作用域把开放式模型输出收敛为有限状态空间。
对应示例:../examples/least_privilege_gateway.py
python3 least_privilege_gateway.py
记录两个配置的小计:配置 A(万能工具 + prompt 禁令)执行了什么、是否外泄;配置 B(粒度工具 + 网关 + 审批门)拦了什么、放行了什么。
gateway() 里找到三处确定性检查的顺序(参数域 → scope → 审批门),回答:http_post 到 collector.evil.example 被直接拒绝而不是进审批门?(廉价确定性检查优先,省人审注意力)hooks.internal.example(白名单内域名)反而进审批门?(egress 白名单=能力授予,高危能力仍需人审)SESSION_SCOPES 加上 "net:post",EGRESS_ALLOWLIST 加上 "collector.evil.example",重跑。观察:合法动作没变多,但外泄变成 True。体会「工具面每放宽一格,战果上限涨一格」。human_approve() 改成 return True(模拟 93% 批准率下的人审),重跑配置 B。观察:审批门失效后,哪些防线仍在?(egress 域名拒绝、scope 拒绝——确定性层不依赖人)ToolSpec("update_shipping_address", "write", "db:write:orders.address", {...}),并让 extract_tool_calls 能从任务文本提取它;验证它进入审批门而非直接执行。🎯 学习重点:必须标清数据来源、信任边界、凭据位置、工具副作用与 egress 路径。
(入口被注入的概率 × 后果严重度) 排序。🎯 学习重点:把绕过样本加入回归集,验证控制失败时仍能 fail closed。
在 Lab 1 的脚本里实现双通道返回:工具结果同时产出「给模型的摘要版」与「给审计日志的完整版」,日志版过一遍 PII 脱敏(正则抹掉邮箱/电话即可)。对应 README 第 5 节:日志脱敏是应用层职责,egress 控制挡不住你自己的日志管道。
🎯 学习重点:实验无需 key,避免把真实凭据引入不可信测试输入。
str | None 类型标注);python3 --version 确认。