Go 的 IsPrivate 与 SSRF 防护:一个标准库 API 的误用
文章开头,我们先考虑这样一个问题:在 Go 里怎么判断一个 IP 是否是私有地址? 很多人第一反应会这样写: ip.IsPrivate() 如果在普通的业务逻辑中,这么写看起来没什么问题。Golang 标准库中关于 net.IP.IsPrivate 和 net/netip.Addr.IsPrivate 的文档也很直接:它判断一个地址是否属于 RFC 1918 定义的 IPv4 私有地址,或者 RFC 4193 定义的 IPv6 ULA 地址。 但是如果在 SSRF 防护代码里这么写,事情就变得危险了。 最近(2026 年 6 月 10 日),在 Go issue tracker 里安全研究员 Jonathan Leitschuh 就提交了一个关于 IsPrivate 的提案:proposal: net: IP.IsPrivate is widely misused as a security primitive,编号 79925。它讨论的不是一个简单的 API 命名问题,而是一个工程安全问题:当标准库提供了一个看起来“刚好能用”的分类函数,开发者很容易误把它当成安全边界。 SSRF 防护里常见的错误写法 SSRF,全称 Server-Side Request Forgery,中文通常叫服务端请求伪造。 假设一个服务提供了“根据 URL 抓取图片”的功能: https://example.com/fetch?url=https://example.org/avatar.png 服务端会根据用户传入的 URL 发起请求,然后把资源下载回来。问题是,攻击者可以把 URL 换成内网地址: ...