教程:使用 govulncheck 查詢和修復易受攻擊的依賴項
Govulncheck 是一種低噪音工具,可幫助您在 Go 專案中查詢和修復易受攻擊的依賴項。它透過掃描專案依賴項以查詢已知的漏洞,然後識別程式碼中對這些漏洞的任何直接或間接呼叫來實現此目的。
在本教程中,您將學習如何使用 govulncheck 掃描簡單的程式以查詢漏洞。您還將學習如何對漏洞進行優先順序排序和評估,以便您可以首先專注於修復最重要的漏洞。
要了解有關 govulncheck 的更多資訊,請參閱 govulncheck 文件,以及 Go 的 關於漏洞管理的博文。我們也希望 收到您的反饋。
先決條件
- Go。我們建議使用最新版本的 Go 來學習本教程。(有關安裝說明,請參閱 安裝 Go。)
- 程式碼編輯器。任何您擁有的編輯器都可以正常工作。
- 命令終端。Go 在 Linux 和 Mac 上的任何終端以及 Windows 上的 PowerShell 或 cmd 中都能很好地工作。
本教程將引導您完成以下步驟
- 建立一個包含易受攻擊依賴項的示例 Go 模組
- 安裝並執行 govulncheck
- 評估漏洞
- 升級易受攻擊的依賴項
建立一個包含易受攻擊依賴項的示例 Go 模組
步驟 1. 首先,建立一個名為 vuln-tutorial
的新資料夾並初始化一個 Go 模組。(如果您不熟悉 Go 模組,請檢視 go.dev/doc/tutorial/create-module。)
例如,從您的主目錄執行以下命令
$ mkdir vuln-tutorial
$ cd vuln-tutorial
$ go mod init vuln.tutorial
步驟 2. 在 vuln-tutorial
資料夾中建立一個名為 main.go
的檔案,並將以下程式碼複製到其中
package main
import (
"fmt"
"os"
"golang.org/x/text/language"
)
func main() {
for _, arg := range os.Args[1:] {
tag, err := language.Parse(arg)
if err != nil {
fmt.Printf("%s: error: %v\n", arg, err)
} else if tag == language.Und {
fmt.Printf("%s: undefined\n", arg)
} else {
fmt.Printf("%s: tag %s\n", arg, tag)
}
}
}
此示例程式將語言標籤列表作為命令列引數,併為每個標籤列印一條訊息,指示它是否已成功解析、標籤未定義或解析標籤時是否出錯。
步驟 3. 執行 go mod tidy
,這將使用您在上一步中新增到 main.go
的程式碼所需的所有依賴項填充 go.mod
檔案。
從 vuln-tutorial
資料夾執行
$ go mod tidy
您應該會看到以下輸出
go: finding module for package golang.org/x/text/language
go: downloading golang.org/x/text v0.9.0
go: found golang.org/x/text/language in golang.org/x/text v0.9.0
步驟 4. 開啟您的 go.mod
檔案以驗證它是否如下所示
module vuln.tutorial
go 1.20
require golang.org/x/text v0.9.0
步驟 5. 將 golang.org/x/text
的版本降級到 v0.3.5,其中包含已知的漏洞。執行
$ go get golang.org/x/text@v0.3.5
您應該會看到以下輸出
go: downgraded golang.org/x/text v0.9.0 => v0.3.5
go.mod
檔案現在應該讀取
module vuln.tutorial
go 1.20
require golang.org/x/text v0.3.5
現在,讓我們看看 govulncheck 的實際應用。
安裝並執行 govulncheck
步驟 6. 使用 go install
命令安裝 govulncheck
$ go install golang.org/x/vuln/cmd/govulncheck@latest
步驟 7. 從您要分析的資料夾(在本例中為 vuln-tutorial
)中執行
$ govulncheck ./...
您應該會看到以下輸出
govulncheck is an experimental tool. Share feedback at https://golang.org.tw/s/govulncheck-feedback.
Using go1.20.3 and govulncheck@v0.0.0 with
vulnerability data from https://vuln.go.dev (last modified 2023-04-18 21:32:26 +0000 UTC).
Scanning your code and 46 packages across 1 dependent module for known vulnerabilities...
Your code is affected by 1 vulnerability from 1 module.
Vulnerability #1: GO-2021-0113
Due to improper index calculation, an incorrectly formatted
language tag can cause Parse to panic via an out of bounds read.
If Parse is used to process untrusted user inputs, this may be
used as a vector for a denial of service attack.
More info: https://pkg.go.dev/vuln/GO-2021-0113
Module: golang.org/x/text
Found in: golang.org/x/text@v0.3.5
Fixed in: golang.org/x/text@v0.3.7
Call stacks in your code:
main.go:12:29: vuln.tutorial.main calls golang.org/x/text/language.Parse
=== Informational ===
Found 1 vulnerability in packages that you import, but there are no call
stacks leading to the use of this vulnerability. You may not need to
take any action. See https://pkg.go.dev/golang.org/x/vuln/cmd/govulncheck
for details.
Vulnerability #1: GO-2022-1059
An attacker may cause a denial of service by crafting an
Accept-Language header which ParseAcceptLanguage will take
significant time to parse.
More info: https://pkg.go.dev/vuln/GO-2022-1059
Found in: golang.org/x/text@v0.3.5
Fixed in: golang.org/x/text@v0.3.8
解釋輸出
*注意:如果您沒有使用最新版本的 Go,您可能會看到標準庫中的其他漏洞。
我們的程式碼受一個漏洞 GO-2021-0113 的影響,因為它直接在易受攻擊的版本 (v0.3.5) 中呼叫了 golang.org/x/text/language
的 Parse
函式。
另一個漏洞 GO-2022-1059 存在於 v0.3.5 版本的 golang.org/x/text
模組中。但是,它被報告為“資訊性”,因為我們的程式碼從未(直接或間接)呼叫過其任何易受攻擊的函式。
現在,讓我們評估漏洞並確定要採取的措施。
評估漏洞
a. 評估漏洞。
首先,閱讀漏洞說明並確定它是否確實適用於您的程式碼和您的用例。如果您需要更多資訊,請訪問“更多資訊”連結。
根據說明,漏洞 GO-2021-0113 在使用 Parse
處理不受信任的使用者輸入時可能導致 panic。假設我們的程式旨在抵禦不受信任的輸入,並且我們擔心拒絕服務,因此該漏洞可能適用。
GO-2022-1059 可能不會影響我們的程式碼,因為我們的程式碼沒有呼叫該報告中任何易受攻擊的函式。
b. 確定行動方案。
為了緩解 GO-2021-0113,我們有一些選擇
- 選項 1:升級到已修復版本。如果有可用的修復程式,我們可以透過升級到模組的已修復版本來刪除易受攻擊的依賴項。
- 選項 2:停止使用易受攻擊的符號。我們可以選擇刪除程式碼中對易受攻擊函式的所有呼叫。我們需要找到替代方案或自己實現。
在本例中,有一個可用的修復程式,並且 Parse
函式對我們的程式至關重要。讓我們將我們的依賴項升級到“已修復於”版本 v0.3.7。
我們決定將修復資訊性漏洞 GO-2022-1059 的優先順序降低,但由於它與 GO-2021-0113 位於同一個模組中,並且它的已修復版本為 v0.3.8,因此我們可以透過升級到 v0.3.8 來輕鬆地同時刪除兩者。
升級易受攻擊的依賴項
幸運的是,升級易受攻擊的依賴項非常簡單。
步驟 8. 將 golang.org/x/text
升級到 v0.3.8
$ go get golang.org/x/text@v0.3.8
您應該會看到以下輸出
go: upgraded golang.org/x/text v0.3.5 => v0.3.8
(請注意,我們也可以選擇升級到 latest
或 v0.3.8 之後的任何其他版本。)
步驟 9. 現在再次執行 govulncheck
$ govulncheck ./...
您現在將看到以下輸出
govulncheck is an experimental tool. Share feedback at https://golang.org.tw/s/govulncheck-feedback.
Using go1.20.3 and govulncheck@v0.0.0 with
vulnerability data from https://vuln.go.dev (last modified 2023-04-06 19:19:26 +0000 UTC).
Scanning your code and 46 packages across 1 dependent module for known vulnerabilities...
No vulnerabilities found.
最後,govulncheck 確認未發現任何漏洞。
透過定期使用命令 govulncheck 掃描您的依賴項,您可以透過識別、優先順序排序和解決漏洞來保護您的程式碼庫。