漏洞管理包括哪些内容?
Go公司的漏洞管理支持由三个明确的支柱组成。
- 数据源,包括。
- 国家漏洞数据库(NVD)。
- GitHub 安全咨询(GHSA)。
- 由Go软件包维护者报告的漏洞,以及
- 由Go团队修复的漏洞。
- 漏洞数据库巩固了所有的原始数据源,以及
- 工具和集成,包括:。

漏洞数据库和软件包发现网站
漏洞数据库是由Go安全团队审查和策划的,它与软件包发现网站集成,目前包括一些有用的功能,如。
- 按时间顺序列出已知的漏洞报告。
- 搜索报告。
- 专门的报告登陆页面,例如 GO-2022-0603,以及
- **我最喜欢的一个!**列出软件包旁边的已知漏洞,包括标准库中的漏洞以及第三方漏洞。

使用govulncheck检测漏洞
govulncheck是一个新的工具,它使用漏洞数据库来检测你的代码库中的已知问题,它类似于我在文章中提到的工具。 Go中的软件架构。安全 - 依赖关系中所介绍的工具,但有三个最大的不同之处。
govulncheck支持扫描已经编译好的二进制文件来搜索漏洞。govulncheck只有在有漏洞的代码被使用时才报告漏洞,并且govulncheck是免费的,并得到Go团队的官方支持。
让我们深入了解一下这个新工具。
安装govulncheck
这篇文章所使用的代码可以在Github上找到。
govulncheck 需要Go 1.18,要安装它请运行以下程序。
go install golang.org/x/vuln/cmd/govulncheck@latest
在写这篇文章的时候,还没有标记的版本,但是你仍然应该考虑将其版本化为一个具体的提交,而不是像我在文章中提到的那样使用
latest。 学习Go。版本管理工具.
检测已编译二进制文件中的漏洞
这个功能要求评估的二进制文件必须是用Go 1.18或更高版本编译的,这是我不记得在其他地方看到的功能之一。让我们来看看下面的例子。
1package main
2
3import (
4 "fmt"
5 "net/url"
6)
7
8func main() {
9 fmt.Println(url.JoinPath("https://go.dev", "../x")) // https://go.dev/../x
10 fmt.Println(url.JoinPath("https://go.dev/", "../x")) // https://go.dev/x
11}
上面的例子演示了Go 1.19中引入的GO-2022-0988漏洞,后来在Go 1.19.1中修复。为了编译这两个版本,我们可以使用docker,对于Go 1.19,运行以下命令将编译一个名为go119 的本地二进制。
docker run --rm \
-v "$PWD":/govulncheck -w /govulncheck \
-e GOOS=darwin -e GOARCH=amd64 \
golang:1.19.0-buster go build -o go119 .
而运行下面的命令将创建一个使用Go 1.19.1编译的名为go1191 的二进制文件。
docker run --rm \
-v "$PWD":/govulncheck -w /govulncheck \
-e GOOS=darwin -e GOARCH=amd64 \
golang:1.19.1-buster go build -o go1191 .
使用govulncheck go119 测试第一个二进制文件go119 将报告该漏洞。

相反,当通过govulncheck go119 ,使用第二个二进制go1191 ,就不会发现漏洞。

这个功能允许追溯评估旧的二进制文件,以确定是否需要立即升级,但是请记住,建议不时地进行定期的Go升级和二进制文件重新编译。
检测对你有实际影响的漏洞
一般来说,漏洞工具会扫描源代码来确定导入的软件包是否包含漏洞,govulncheck ,通过检查我们的代码来评估事实上是否调用了漏洞代码,从而避免了错误的否定和嘈杂的报告。
让我们看看两个例子,它们都是在其go.mod ,报告为GO-2022-0603,导入了一个有漏洞的包。
3go 1.19
4
5require gopkg.in/yaml.v3 v3.0.0
第一个例子包括使用有漏洞的代码。
7func main() {
8 var t interface{}
9 yaml.Unmarshal([]byte("0: [:!00 \xef"), &t)
10}
执行govulncheck ./... ,正确地报告了该漏洞。

第二个例子导入了有漏洞的包**,但没有**调用受影响的函数。
7func main() {
8 type T struct {
9 F int `yaml:"a,omitempty"`
10 B int
11 }
12
13 yaml.Marshal(&T{B: 2}) // Returns "b: 2\n"
14}
在这种情况下,执行govulncheck ./... ,正确地报告了漏洞**,但**它表明我们没有使用它,这很重要,因为它可以正确地确定补救措施的优先次序,我们肯定需要更新包,但没有紧急的理由,这就是最大的区别。

使用go.mod 来确定漏洞的工具不会有这种细微的区别,例如Snyk无论如何都会检测两种情况:使用有漏洞的代码和不使用有漏洞的代码。
总结
这个新功能对Go生态系统来说是一个非常受欢迎的补充,虽然我不认为这个工具会取代现有的工具,但我相信它会对它们进行补充,我期待着看到在未来的版本中会出现什么。