Skip to content

URL、审批与数据最小化 ​

URL看起来合法不表示可以访问。攻击者可以利用内网地址、重定向或域名解析变化触达不该访问的服务。高风险动作还需绑定具体参数的审批,日志则要在采集前排除秘密。

先从严格允许列表开始 ​

标准库完整实验只验证URL语法与允许的主机,不执行请求。生产还需连接时解析地址、出站网络策略、重定向逐跳复验以及响应大小/时间限制;这段函数不能单独宣称防住全部SSRF。

python
from urllib.parse import urlsplit

def allowed_url(raw):
    try:
        u=urlsplit(raw)
        return (u.scheme == "https" and u.hostname == "docs.example.com"
                and u.port in (None,443) and u.username is None and u.password is None
                and not u.fragment and "\\" not in raw)
    except ValueError:
        return False
assert allowed_url("https://docs.example.com/guide")
assert not allowed_url("https://docs.example.com@evil.example/guide")
assert not allowed_url("http://127.0.0.1/")
assert not allowed_url("https://docs.example.com:bad/")
print("URL policy checked")

@前是用户名而不是目标主机,所以用字符串前缀匹配会错。路径访问需resolve后的真实路径在允许目录内,并考虑符号链接和检查后替换的竞态;命令工具应固定程序与参数列表,不把模型字符串交给shell解释。

审批不能与动作脱节 ​

批准记录保存用户、任务、资源、规范化参数摘要、资源版本、有效期与批准者。执行前重新计算摘要并鉴权,改参数、过期或撤权都拒绝。幂等键绑定同一业务动作,网络超时先查效果再重试。沙箱凭证只授予所需资源,不能把宿主的全量环境变量交给代码执行器。

数据从哪里泄漏 ​

模型请求、工具返回、trace、记忆、Embedding、缓存与备份都可能保留原文。按数据分类设保留期和删除责任;删除会话并不会自动删除向量、日志或外部供应商副本。发送给供应商前只保留任务所需字段,并核对其区域、保留和数据使用条款;产品更新后重新核对,不把一次配置当永久保证。

日志采用字段允许列表并约束字段值。例如只记录错误码枚举而不是任意error文本;哈希用户ID也可能可关联,不等于匿名。输出HTML要转义,不允许任意脚本和外链加载;Markdown图片也可能向外部服务器暴露访问。第三方SDK、MCP服务、解析器与模型文件都需要版本锁定和来源审查。

练习 ​

allowed_url还应拒绝明确非443端口与带密码URL;再写safe_event只接受event枚举tool_ok/tool_denied与整数duration_ms,丢弃prompt、secret和任意error文本。

核对本章答案

下一章

用心记录每一步成长