SSRF
Agent HTTP Tool 的 SSRF 防护:窄参数、URL 校验、DNS Rebinding、Egress Policy、凭据隔离与审计。
SSRF
Agent生成的URL和Tool Arguments全部按不可信输入处理。Prompt不是防火墙,JSON Schema也不是;strings.HasPrefix(url, "https://")更只能说明这串字符开头比较礼貌。

Agent场景中的SSRF风险
传统SSRF来自用户可控URL,Agent Tool又多了一层:用户可以通过自然语言、网页内容、检索文档或Prompt Injection间接诱导模型构造请求。攻击目标可能是:
127.0.0.1上的管理服务;- RFC1918私网、IPv6 ULA、Link-local地址;
- 云Metadata服务;
- Kubernetes Service、Docker Socket代理、内部Dashboard;
- 带Tool凭据的批准域名上非预期Path;
- 重定向后的内部地址;
- DNS Rebinding前后解析到不同IP。
所以防护必须落在Executor和网络层,不能让模型负责判断自己是否被诱导。
Tool输入的最小能力原则
优先设计窄Verb:
不推荐:http_get(url, headers)
推荐:query_prometheus(
service_id,
metric_name,
start_time,
end_time
)
后端根据service_id从受控Registry取得Base URL,Path和Query由模板构造。模型只选择业务参数,不控制Scheme、Host、Port和Credential。缩小Tool能力面能够显著降低后续校验复杂度。
URL解析与Allowlist
必须使用标准URL Parser完成一次规范化,再基于结构字段验证:
- 只允许
https,必要的内部协议单独建Tool; - Host使用精确Allowlist或受控子域规则,不使用不严格的字符串后缀匹配;
- 拒绝Userinfo,如
trusted.com@evil.com; - 拒绝非预期Port;
- 规范化Path,限制可访问Endpoint;
- Header由服务端模板产生,拒绝模型注入
Host、Authorization等敏感头; - 不接受歧义IP格式、整数IP和混淆编码。
Allowlist应该绑定逻辑Service和Tenant。即使Host合法,低权限Agent也不该访问管理员Path。
DNS解析与IP检查
Host通过后还不够。解析全部A/AAAA地址并拒绝:
- Loopback;
- Private Network;
- Link-local;
- Multicast、Unspecified、Reserved;
- IPv6 ULA与IPv4-mapped IPv6;
- 云Metadata地址与环境中特定控制面网段。
检查后应连接到已验证并固定的IP,同时保留原始Hostname做TLS SNI和证书校验,避免校验时解析公网IP、连接时又重新解析到私网的DNS Rebinding。
Redirect与协议降级
最简单的策略是禁用Redirect。确实需要时,每一跳都要重新执行完整流程:Parse → Scheme/Host/Port → DNS → IP Range → Credential Scope。只验证第一跳会允许攻击者通过302将请求转向169.254.169.254等受限地址。
拒绝从HTTPS降级到HTTP,限制最大跳数,并避免在跨Host跳转时携带Authorization和Cookie。
网络层Egress Policy
应用校验可能有Bug,所以还要让网络本身说“不”:
- Agent Worker放独立Network Namespace或VPC Segment;
- 默认拒绝Egress,只允许Egress Proxy;
- Proxy按DNS Name、IP、Port和Identity授权;
- 阻断Metadata、控制面、数据库和内部管理网段;
- 不同Tool使用不同Service Account与Credential;
- 记录最终Destination IP、SNI、Response Size和Decision。
纵深防御的目标是:即使应用层校验存在缺陷,网络层仍能阻止请求访问未授权目标。
资源限制与响应处理
SSRF不仅可能访问未授权地址,也可能利用合法地址造成资源耗尽:
- Connect、TLS、First Byte、Total Timeout;
- 最大Response Body与解压后大小;
- Content-Type Allowlist;
- 最大并发、Rate Limit、Circuit Breaker;
- 禁止自动执行响应中的脚本、链接或二次Tool Call;
- 二进制内容隔离解析,防止Parser漏洞。
外部响应仍是不可信内容。送进LLM前加来源边界和Instruction Isolation,不让网页里一句“忽略之前命令”从数据层升职为系统指令。
凭据与多租户
Credential由Executor按Tool、Tenant和Target注入,模型永远看不到明文。不要允许调用者自带Authorization Header;不要让一个能查监控的Token顺便访问配置写接口;Trace中只记录Credential ID和Scope,不记录Secret。
审批界面不能只显示“即将调用HTTP工具”,还应展示规范化后的Host、Path、Method、数据分类和副作用,使审批者能够准确理解授权范围。
测试矩阵
至少覆盖:
127.0.0.1 / localhost / ::1
10.0.0.0/8 / 172.16.0.0/12 / 192.168.0.0/16
169.254.169.254
IPv4-mapped IPv6
userinfo URL
整数与混淆IP
Allowlist子域绕过
公网 → 私网 Redirect
DNS Rebinding
超大Response / 解压膨胀攻击 / 慢响应
跨Tenant Credential
测试既要覆盖URL Validator单元测试,也要在隔离网络中验证Egress规则确实拒绝请求。仅使用Mock无法证明真实网络策略有效。
项目回答模板
Agent提供的URL和Tool参数全部视为不可信输入。我们首先避免提供任意URL Tool,仅允许模型传入Service标识和窄业务参数;Executor使用标准Parser校验Scheme、Host、Port和Path Allowlist,解析全部A/AAAA记录并拒绝私网、Loopback、Link-local和Metadata地址,连接固定校验后的IP并验证TLS Hostname,以防止DNS Rebinding。Redirect默认关闭;确需开启时逐跳重新校验。网络层使用默认拒绝的Egress Proxy作为最终边界,凭据按Tool和Tenant注入,同时限制Timeout和Body Size,并记录脱敏Audit Trace。
高频追问
- 为什么Host Allowlist仍挡不住DNS Rebinding?
- 校验IP后直接连接IP,TLS证书该如何验证?
- 为什么JSON Schema和Prompt不能算安全边界?
- Redirect为什么必须逐跳检查?
- Allowlist域名被接管或CNAME变化怎么办?
- SSRF测试为什么需要真实网络策略而不只是Mock?