修復以 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 來自 2 個來源:

  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
  • 否則,你的映像需要這類二進位檔才能正常運作,而你就必須採取較困難的途徑。作為適用於任何靜態連結執行檔的一般修復方式,請自行從原始碼建置一個執行檔(例如,作為映像的 CICD 管線或 Dockerfile 的一部分),並使用最新的 golang SDK。大多數時候,你只是想快速修復一些 CVE(這些 CVE 恰好與 golang 有關,而你又不是 golang 專家),此時容器化系統與 go 毫無關係。這需要額外的努力,因此祝你好運。

參考資料:

評論

在 GitHub 上閱讀或評論(發表評論需要登入)