<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Golang on 楠楠自瑜</title>
    <link>https://cnutshell.net/tags/golang/</link>
    <description>Recent content in Golang on 楠楠自瑜</description>
    <generator>Hugo -- 0.157.0</generator>
    <language>zh-cn</language>
    <lastBuildDate>Sat, 13 Jun 2026 15:53:58 +0800</lastBuildDate>
    <atom:link href="https://cnutshell.net/tags/golang/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Go 的 IsPrivate 与 SSRF 防护：一个标准库 API 的误用</title>
      <link>https://cnutshell.net/golang/issue-79925/</link>
      <pubDate>Sat, 13 Jun 2026 15:53:58 +0800</pubDate>
      <guid>https://cnutshell.net/golang/issue-79925/</guid>
      <description>&lt;p&gt;&lt;img alt=&#34;go isprivate ssrf cover&#34; loading=&#34;lazy&#34; src=&#34;https://cdn.jsdelivr.net/gh/cuiguoke/blogger-assets/images/20260613155426779.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;文章开头，我们先考虑这样一个问题：在 Go 里怎么判断一个 IP 是否是私有地址？&lt;/p&gt;
&lt;p&gt;很多人第一反应会这样写：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;ip&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;IsPrivate&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;如果在普通的业务逻辑中，这么写看起来没什么问题。Golang 标准库中关于 &lt;code&gt;net.IP.IsPrivate&lt;/code&gt; 和 &lt;code&gt;net/netip.Addr.IsPrivate&lt;/code&gt; 的文档也很直接：它判断一个地址是否属于 RFC 1918 定义的 IPv4 私有地址，或者 RFC 4193 定义的 IPv6 ULA 地址。&lt;/p&gt;
&lt;p&gt;但是如果在 SSRF 防护代码里这么写，事情就变得危险了。&lt;/p&gt;
&lt;p&gt;最近（2026 年 6 月 10 日），在 Go issue tracker 里安全研究员 &lt;a href=&#34;https://github.com/JLLeitschuh&#34;&gt;Jonathan Leitschuh&lt;/a&gt; 就提交了一个关于 &lt;code&gt;IsPrivate&lt;/code&gt; 的提案：&lt;a href=&#34;https://github.com/golang/go/issues/79925&#34;&gt;proposal: net: IP.IsPrivate is widely misused as a security primitive&lt;/a&gt;，编号 79925。它讨论的不是一个简单的 API 命名问题，而是一个工程安全问题：当标准库提供了一个看起来“刚好能用”的分类函数，开发者很容易误把它当成安全边界。&lt;/p&gt;
&lt;h2 id=&#34;ssrf-防护里常见的错误写法&#34;&gt;SSRF 防护里常见的错误写法&lt;/h2&gt;
&lt;p&gt;SSRF，全称 Server-Side Request Forgery，中文通常叫&lt;strong&gt;服务端请求伪造&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;假设一个服务提供了“根据 URL 抓取图片”的功能：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;https://example.com/fetch?url=https://example.org/avatar.png
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;服务端会根据用户传入的 URL 发起请求，然后把资源下载回来。问题是，攻击者可以把 URL 换成内网地址：&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
