Go团队宣布模糊测试支持可以进行测试了。该项目的主要目标是为该语言的开发者和用户创造一个统一的、端到端的体验,包括强大的模块支持,与go
命令的整合,以及新的编译器仪表。
根据谷歌工程师Katie Hockman(模糊设计草案的作者)的说法,这个项目旨在使模糊测试成为测试Go程序的一流选择,就像运行单元测试一样容易。
由于模糊测试可以接触到人类经常错过的边缘案例,所以模糊测试对于发现安全漏洞和漏洞特别有价值。模糊测试在历史上主要是由安全工程师编写的,黑客也可能使用类似的方法来恶意寻找漏洞。然而,编写模糊测试目标不需要限制在具有安全专业知识的开发人员身上。
Hockman解释说,对于Go社区来说,Fuzzing并不陌生,比如go-fuzz及其衍生的fzgo工具。不过,由于需要使用非标准的工具,需要分离测试文件或构建标签,缺乏强大的模块支持等原因,它们给开发者带来了一些不必要的开销。
下面是一个Google提供的测试net/url包的行为的模糊目标的例子。
// +build gofuzzbeta
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)
}
})
}
一个模糊目标是以FuzzXyz
函数的形式提供的,它接收一个*testing.F
参数。f.Add
函数可以用来填充_种子语料库_,也就是用户指定的模糊目标的输入集。f.Fuzz
函数对语料库中的每个项目都要执行。除了种子语料库之外,f.Fuzz
还测试testdata/corpus/FuzzTarget
中提供的输入。
当开发者使用-fuzz
标志go test
,Go模糊引擎将针对生成的语料库运行测试功能,而突变器将生成新的输入,试图发现一个错误或一个 崩溃者.
Go fuzzing测试版在Go开发分支中可用。不幸的是,目前还没有时间表说明它何时会被纳入稳定的Go版本,Hockman排除了它会在Go 1.17中登陆的可能性。
由于处于测试阶段,Go的模糊性还没有完成,可能会有变化。Hockman说,还有一些额外的功能已经在进行中,比如一次测试多个目标,支持字典,为突变器增加自定义生成器等等。