使用 govulncheck 尋找並修復易受攻擊的依賴項
Govulncheck 是一個低噪音工具,幫助你發現並修復 Go 專案中的易受攻擊依賴項。它透過掃描專案的依賴項來查找已知漏洞,然後識別程式碼中對這些漏洞的直接或間接呼叫。
在本教學中,你將學習如何使用 govulncheck 掃描簡單程式的漏洞。你還將學習如何優先處理和評估漏洞,以便首先專注於修復最重要的漏洞。
要了解有關 govulncheck 的更多資訊,請參閱 govulncheck 文件,以及這篇關於漏洞管理的 部落格文章。我們也樂於 聽取你的反饋。
先決條件
- 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: 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 is an experimental tool. Share feedback at https://go.dev/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
由於索引計算錯誤,格式不正確的語言標籤會導致 Parse 因越界讀取而發生恐慌。
如果 Parse 用於處理不受信任的用戶輸入,這可能用作拒絕服務攻擊的載體。
更多資訊: https://pkg.go.dev/vuln/GO-2021-0113
模組: golang.org/x/text
發現於: golang.org/x/text@v0.3.5
修復於: golang.org/x/text@v0.3.7
呼叫堆疊在你的程式碼中:
main.go:12:29: vuln.tutorial.main 呼叫 golang.org/x/text/language.Parse
=== 資訊性漏洞 ===
在你的匯入套件中發現了 1 個漏洞,但沒有呼叫堆疊導致使用此漏洞。你可能不需要採取任何行動。詳情見 https://pkg.go.dev/golang.org/x/vuln/cmd/govulncheck
漏洞 #1: GO-2022-1059
攻擊者可以透過建構一個 Accept-Language 標頭來導致拒絕服務,ParseAcceptLanguage 將花費大量時間解析。
更多資訊: https://pkg.go.dev/vuln/GO-2022-1059
發現於: golang.org/x/text@v0.3.5
修復於: golang.org/x/text@v0.3.8
解釋輸出
*注意:如果你沒有使用最新版本的 Go,你可能會看到來自標準函式庫的額外漏洞。
我們的程式碼受到一個漏洞的影響,
GO-2021-0113,因為它直接呼叫了 golang.org/x/text/language 的 Parse 函數,且該函數處於易受攻擊的版本(v0.3.5)。
另一個漏洞 GO-2022-1059 存在於 golang.org/x/text 模組的 v0.3.5 版本中。然而,它被報告為「資訊性」,因為我們的程式碼從未(直接或間接)呼叫其任何易受攻擊的函數。
現在,讓我們評估漏洞並決定要採取的行動。
評估漏洞
a. 評估漏洞。
首先,閱讀漏洞描述並確定它是否真的適用於你的程式碼和使用場景。如果你需要更多資訊,請造訪「更多資訊」連結。
根據描述,漏洞 GO-2021-0113 會在 Parse 用於處理不受信任的用戶輸入時導致恐慌。假設我們打算讓我們的程式能夠承受不受信任的輸入,並且我們擔心拒絕服務,因此該漏洞可能適用。
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 is an experimental tool. Share feedback at https://go.dev/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 掃描你的依賴項,你可以透過識別、優先處理和解決漏洞來保護你的程式碼庫。