SSRF 防护
SSRF(Server-Side Request Forgery,服务端请求伪造)是攻击者利用服务器发起内网请求的攻击方式。HTTPC 默认开启 SSRF 防护。
默认行为
cfg := httpc.DefaultConfig()
// AllowPrivateIPs = false → 默认阻止所有私有 IP默认阻止的 IP 范围:
| 范围 | CIDR | 说明 |
|---|---|---|
| IPv4 回环 | 127.0.0.0/8 | localhost |
| A 类私有 | 10.0.0.0/8 | 内网 |
| B 类私有 | 172.16.0.0/12 | 内网 |
| C 类私有 | 192.168.0.0/16 | 内网 |
| 链路本地 | 169.254.0.0/16 | 自动配置 |
| CGNAT | 100.64.0.0/10 | 运营商级 NAT(含阿里云元数据 100.100.100.200) |
| E 类保留 | 240.0.0.0/4 | 保留地址 |
| IPv6 回环 | ::1/128 | localhost |
| IPv6 本地 | fc00::/7 | 唯一本地地址 |
| IPv6 链路 | fe80::/10 | 链路本地 |
上表为主要范围。完整阻止列表还包含
0.0.0.0/8、TEST-NET(192.0.2.0/24、198.51.100.0/24、203.0.113.0/24等)、IPv6 文档前缀2001:db8::/32与 NAT6464:ff9b::/96,详见源码isPrivateOrReservedIP。
CIDR 豁免
在微服务环境中,可能需要访问内部服务:
cfg := httpc.DefaultConfig()
cfg.Security.SSRFExemptCIDRs = []string{
"10.0.0.0/8", // VPC 内部
"100.64.0.0/10", // Tailscale VPN
"172.20.0.0/16", // Kubernetes Service CIDR
}WARNING
豁免 CIDR 应尽量精确。避免使用过大的范围(如 0.0.0.0/0),否则等于禁用 SSRF 防护。
按请求豁免私有 IP
如果仅需对个别请求放行私有 IP(例如调用 localhost 健康检查端点),无需全局启用 AllowPrivateIPs,可使用 WithAllowPrivateIPs 请求选项仅对该次请求放行:
// 默认客户端阻止私有 IP;此调用按请求放行
result, err := httpc.Get("http://localhost:8080/health",
httpc.WithAllowPrivateIPs(true),
)WARNING
仅对可信且非来自用户输入的 URL 启用此选项。SSRF 防护的目的是防止攻击者诱导你的进程访问内网端点,按请求禁用会为该次调用重新引入此风险。若整个客户端都需要访问内部服务,请在 Config 上设置 Security.AllowPrivateIPs = true。
DNS 重绑定防护
HTTPC 采用"解析 - 验证 - 直连"模式防止 DNS 重绑定攻击:
- 解析域名为 IP 地址
- 验证所有解析出的 IP 是否为私有地址
- 直接拨号到已验证的 IP(而非再次解析域名)
// 攻击场景:
// 1. 攻击者控制 evil.com 的 DNS
// 2. 第一次解析返回公网 IP(通过验证)
// 3. 实际连接时 DNS 返回 127.0.0.1(绕过验证)
//
// HTTPC 防御:验证后直接使用已验证的 IP 拨号,不再重新解析重定向 SSRF 检查
重定向目标同样经过 SSRF 验证:
// 假设请求 public-api.com,服务端返回 302 重定向到 http://169.254.169.254/
// HTTPC 会验证重定向目标的 IP,阻止对元数据服务的访问重定向域名白名单
cfg := httpc.DefaultConfig()
cfg.Security.RedirectWhitelist = []string{
"api.example.com",
"auth.example.com",
"*.cdn.example.com", // 支持通配符
}
// 非白名单域名的重定向会被阻止云环境元数据防护
各云平台的元数据服务地址:
| 平台 | 地址 | 说明 |
|---|---|---|
| AWS | 169.254.169.254 | 实例元数据 |
| GCP | metadata.google.internal | 元数据服务 |
| Azure | 169.254.169.254 | 实例元数据 |
| 阿里云 | 100.100.100.200 | 元数据服务 |
HTTPC 默认阻止 AWS/Azure 元数据访问(169.254.169.254 在 169.254.0.0/16 阻止列表中)。GCP 元数据(metadata.google.internal)通过 DNS 解析验证被阻止。
WARNING
阿里云元数据(100.100.100.200)位于 CGNAT 范围(100.64.0.0/10),HTTPC 默认阻止该范围,因此阿里云元数据访问默认即被拦截。若因 Tailscale/WireGuard 等 VPN 或内部路由确需访问该范围,须显式通过 SSRFExemptCIDRs: []string{"100.64.0.0/10"} 豁免——豁免后该范围内的阿里云元数据也将可达,请评估风险。
完全禁用 SSRF 防护
仅在测试环境中使用:
// TestingConfig 禁用 SSRF 防护
client, _ := httpc.New(httpc.TestingConfig())
// 或手动配置
cfg := httpc.DefaultConfig()
cfg.Security.AllowPrivateIPs = trueDANGER
生产环境永远不要设置 AllowPrivateIPs = true。
最佳实践
- 使用
SecureConfig()作为安全基线 - 仅豁免必要的 CIDR 范围
- 配置
RedirectWhitelist限制重定向目标 - 定期审计
SSRFExemptCIDRs配置 - 使用审计中间件记录所有请求