Go Fuzzing 进入 Beta 阶段
凯蒂-霍克曼和杰伊-康罗德
2021年6月3日
我们很高兴地宣布,原生模糊测试已经准备好在 TIP 上进行测试了!
Fuzzing是一种自动化测试,它持续操纵程序的输入,以发现恐慌或错误等问题。这些半随机的数据突变可以发现现有单元测试可能错过的新的代码覆盖范围,并发现边缘案例的bug,否则这些bug就不会被注意到。由于模糊测试可以接触到这些边缘案例,所以模糊测试对于发现安全漏洞特别有价值。
关于这项功能的更多细节,请参见golang.org/s/draft-fuzzing-design。
开始使用
要开始使用,你可以运行以下程序
$ go install golang.org/dl/gotip@latest
$ gotip download
这将从主分支构建Go工具链。运行这个命令后,gotip
可以作为go
命令的直接替代品。现在你可以运行以下命令
$ gotip test -fuzz=Fuzz
编写一个模糊目标
一个模糊目标必须在 _test.go 文件中作为一个函数以FuzzXxx
的形式出现。这个函数必须通过一个` testing.F 参数,就像一个
*testing.T 参数被传递给
TestXxx ` 函数一样。
下面是一个测试 net/url package 行为的模糊目标的例子。
//go:build go1.18
// +build go1.18
package fuzz
import (
"net/url"
"reflect"
"testing"
)
func FuzzParseQuery(f *testing.F) {
f.Add("x=1&y=2")
f.Fuzz(func(t *testing.T, queryStr string) {
query, err := url.ParseQuery(queryStr)
if err != nil {
t.Skip()
}
queryStr2 := query.Encode()
query2, err := url.ParseQuery(queryStr2)
if err != nil {
t.Fatalf("ParseQuery failed to decode a valid encoded query %s: %v", queryStr2, err)
}
if !reflect.DeepEqual(query, query2) {
t.Errorf("ParseQuery gave different query after being encoded\nbefore: %v\nafter: %v", query, query2)
}
})
}
你可以在pkg.go.dev阅读更多关于模糊处理的信息,包括Go模糊处理概述 (链接:https://pkg.go.dev/testing@master#hdr-Fuzzing
)和godoc for the new testing.F
type (链接:https://pkg.go.dev/testing@master#F
)。
期望值
这是一个仍处于测试阶段的新功能,所以你应该期待一些bug和不完整的功能集。请查看标记为 「fuzz」的问题追踪器以了解现有bug和缺失功能的最新情况。
请注意,fuzzing会消耗大量的内存,在运行时可能会影响你的机器性能。 go test -fuzz
默认为在$GOMAXPROCS
进程中并行运行fuzzing。你可以通过在go test
中明确设置-parallel
标志来降低模糊处理时使用的进程数。如果你想了解更多信息,可以运行 "gotip help testflag "来阅读go test
命令的文档。
还要注意的是,模糊引擎在运行时,会将扩大测试范围的数值写入$GOCACHE/fuzz
的模糊缓存目录。目前对写入模糊缓存的文件数量或总字节数没有限制,所以它可能会占用大量的存储空间(即几个GB)。你可以通过运行gotip clean -fuzzcache
来清除模糊缓存。
下一步是什么?
这项功能将在Go 1.18中开始使用。
如果你遇到任何问题或有关于功能的想法,请提交问题。
关于该功能的讨论和一般反馈,你也可以参加Gophers Slack的#fuzzing频道。
祝使用fuzzing愉快!
本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
推荐文章: