修复基于 Golang 的静态链接可执行文件中的 CVE

最后更新: 2023-11-09 07:27:26 +0800 +0800
tags: Cve | Docker
原文以英文撰写。您正在阅读AI翻译版本。

gosu 是 su/sudo 的容器友好替代方案,使用 Go 编写。它包含在我们的一个生产镜像的基础镜像中,该镜像会触发 https://nvd.nist.gov/vuln/detail/CVE-2025-68121.

所有基于 Golang 的静态链接可执行文件的通用注意事项 #

静态链接的 Golang 程序中的 CVE 来源有两个:

  1. 软件自身的代码。这只是传统的软件 CVE
  2. Golang 标准 SDK;官方公告。这些 CVE 存在于用于构建特定可执行文件的工具链中。

大多数情况下,应归咎于 Golang SDK,而修复此类 CVE 就像使用最新的 Golang SDK 重新构建程序一样简单。

我们以 gosu 为例,但你可以将其替换为任意静态链接的可执行文件:

sh
#!/bin/bash

set -eux

CONT_NAME=tmp_mysqlcontainer

docker create --pull=always --name $CONT_NAME mysql:latest 
docker cp $CONT_NAME:/usr/local/bin/gosu /tmp/gosu
docker run -it --rm -v /tmp/gosu:/tmp/gosu golang:latest

以及在 Docker 中:

sh
ldd /tmp/gosu/gosu
#	not a dynamic executable
go version /tmp/gosu/gosu
# /tmp/gosu/gosu: go1.24.6

由于 https://nvd.nist.gov/vuln/detail/CVE-2025-68121 会影响所有低于 1.24.13 的 Golang 版本,我们可以确定这个程序是由存在漏洞的 Golang 工具链构建的。

现实世界中的问题 #

有些软件维护者拒绝持续重新构建其二进制版本。 主要理由是,他们的代码不会调用受影响的 Golang 标准库。 官方 CVE 检查器 golang.org/x/vuln/cmd/govulncheck@latest 根据函数调用路径报告 CVE,而不是简单地依据构建程序的 Golang 版本:

sh
go run golang.org/x/vuln/cmd/govulncheck@latest -mode=binary /tmp/gosu/gosu
# === Symbol Results ===
# 
# No vulnerabilities found.
# 
# Your code is affected by 0 vulnerabilities.
# This scan also found 2 vulnerabilities in packages you import and 31
# vulnerabilities in modules you require, but your code doesn't appear to call
# these vulnerabilities.
# Use '-show verbose' for more details.

尽管这一理由合理,但根据你所在工作环境的安全策略,你可能能够或无法规避这一问题。

修复方案 #

  • 若要快速修复,只需删除 gosu(如果不需要它):

    dockerfile
    RUN rm /usr/local/bin/gosu
  • 否则,你的镜像需要此类二进制文件才能正常工作,此时就必须采用更复杂的方案。对于任意静态链接的可执行文件,通用的修复方法是自行从源代码构建一个(例如,作为镜像 CI/CD 流水线或 Dockerfile 的一部分),并使用最新的 Golang SDK。很多时候,你只是想快速修复一些 CVE(这些 CVE 恰好与 Golang 有关,而你并不是 Golang 专家),此时你的容器化系统与 Go 毫无关系。这需要额外的工作,祝你顺利。

参考:

评论

在 GitHub 上阅读或评论(发表评论需要登录)