资讯 golang.org/x/net v0.62.0 修的两个 html 漏洞:文本节点合并的 O(n²) 与 raw text 渲染的命名空间判断

2026-11-01 21:03:15

golang.org/x/net v0.62.0 修的两个 html 漏洞:文本节点合并的 O(n²) 与 raw text 渲染的命名空间判断

Go 安全团队在 2026-10-27 发布 golang.org/x/net v0.62.0,修掉 html 包里的两个安全问题。发布公告:。两个问题都能由不可信的 HTML 输入触发,如果代码里用 html.Parse 处理用户提交的内容,需要一起看。

一、合并文本节点时的二次复杂度 — CVE-2026-78661 / GO-2026-6860

  • Go issue:
  • CL:
  • 报告者:Markus Magnuson

问题出在 addText 和 fosterParent 合并相邻文本节点的实现上。原实现用字符串拼接往已有 TextNode 的 Data 追加:

n.Data += text

每处理一个 token 都会重新分配并复制一遍累积的字符串,代价随累积长度线性增长,处理 n 个 token 就是 O(n²) 的分配与字节复制。

触发条件是输入里包含大量短文本片段,且片段之间隔着被忽略的结束标签。这类输入会让解析器频繁走到「追加到上一个文本节点」的分支,而不是新建节点,于是每次都复制一遍已经攒起来的 Data。

影响面按 Snyk 的评级是 high,CWE-400(资源耗尽)。攻击路径为网络可达,不需要权限,也不需要特殊配置——把构造好的 HTML 喂给 html.Parse 就能吃掉 CPU 与内存。修复版本为 0.62.0。

修复方式是把累积从字符串挪到解析期:解析过程中按节点把文本累积到 byte slice,解析结束时一次性 materialize 成 Data 字符串。追加变成摊还 O(1),整体回到线性。

二、raw text 渲染时未走完整祖先命名空间链 — CVE-2026-97045 / GO-2026-6866

  • Go issue:
  • CL:
  • 报告者:Ali Sherif

第二个问题在 childTextNodesAreLiteral。这个函数负责判断某个子文本节点在渲染输出时能不能当作 literal text 直接输出。它向上遍历树,一旦遇到 HTML integration point 就停下,把判断基准定在最近的 foreign ancestor(不同命名空间祖先)上。

问题在于,这个 integration point 本身可能是一个被 foster-parent 到 foreign namespace 的元素的后代。只看最近一层,就会漏掉中间发生的命名空间转换:解析器在重新解析渲染输出时,会把子树解析到另一个 foreign namespace 里去,两次解析的结果不一致。

修复方式是继续走完整条祖先链,不再提前停:只有当每一次从非空 namespace 出发的转换都发生在 HTML integration point 时,才输出 literal text。判断条件从「最近一层对得上」变成「整条链上的每一跳都对得上」。

这个漏洞能在「解析 → 序列化 → 再解析」的链路上被利用,典型场景是把用户 HTML 解析后重新渲染再交回给解析器(sanitizer、模板、富文本处理都会出现这种往返)。修复版本同为 0.62.0。

三、确认自己是否受影响

先看模块版本。golang.org/x/net 经常作为间接依赖被拉进来,用 go list -m 确认实际选中的版本:

go list -m golang.org/x/net
# 或者看全图
go list -m all | grep golang.org/x/net

输出 v0.62.0 及以上即已修复;低于该版本就需要升级,包括 v0.0.0-2026xxxx 这类伪版本——它们按提交时间排序,需要确认对应的提交已包含修复补丁后再判断。

再看调用点是否可达。govulncheck 会按 GO 编号匹配并做调用图分析,能区分「依赖里有漏洞」和「你的代码真的会走到漏洞函数」:

go install golang.org/x/vuln/cmd/govulncheck@latest
govulncheck ./...

报告里出现 GO-2026-6860 或 GO-2026-6866 即为命中;如果只出现在 module 层面而没有调用栈,说明是依赖引入但当前代码路径不可达,仍建议随下一次升级一并处理。

升级命令:

go get golang.org/x/net@v0.62.0
go mod tidy

四、发行版与历史问题

Debian 的跟踪页面显示,bookworm(1:0.7.0)、trixie(1:0.27.0)、forky(1:0.61.0)都在受影响范围内,sid(1:0.62.0)已修复。用发行版打包的 Go 工具链或依赖系统包的二进制,需要等对应的安全更新。

html.Parse 这类二次复杂度与无限解析的问题不是第一次出现,历史上还有 CVE-2026-42506、CVE-2026-42502、CVE-2026-27136、CVE-2026-25681、CVE-2026-25680、CVE-2025-58190、CVE-2025-47911 等一串。共同点都是把不可信 HTML 交给解析器,因此这类入口除了跟版本,也值得在调用侧加上输入长度与解析耗时的上限。

复制全文 生成海报 Go 安全 html 依赖升级

推荐文章

程序员茄子在线接单