2021-08-03 07:54:24 +03:00
|
|
|
|
---
|
|
|
|
|
title: Fuzzing is Beta Ready
|
|
|
|
|
date: 2021-06-03
|
|
|
|
|
by:
|
|
|
|
|
- Katie Hockman
|
|
|
|
|
- Jay Conrod
|
|
|
|
|
tags:
|
|
|
|
|
- fuzz
|
|
|
|
|
- testing
|
2021-09-22 21:43:43 +03:00
|
|
|
|
summary: Native Go fuzzing is now ready for beta testing on tip.
|
2021-08-03 07:54:24 +03:00
|
|
|
|
---
|
2021-06-02 22:39:51 +03:00
|
|
|
|
|
|
|
|
|
|
2021-09-22 21:43:43 +03:00
|
|
|
|
We are excited to announce that native fuzzing is ready for beta testing on tip!
|
2021-06-02 22:39:51 +03:00
|
|
|
|
|
|
|
|
|
Fuzzing is a type of automated testing which continuously manipulates inputs to
|
|
|
|
|
a program to find issues such as panics or bugs. These semi-random data
|
|
|
|
|
mutations can discover new code coverage that existing unit tests may miss, and
|
|
|
|
|
uncover edge case bugs which would otherwise go unnoticed. Since fuzzing can
|
|
|
|
|
reach these edge cases, fuzz testing is particularly valuable for finding
|
|
|
|
|
security exploits and vulnerabilities.
|
|
|
|
|
|
|
|
|
|
See
|
2021-11-18 06:34:23 +03:00
|
|
|
|
[golang.org/s/draft-fuzzing-design](/s/draft-fuzzing-design)
|
2021-06-02 22:39:51 +03:00
|
|
|
|
for more details about this feature.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## Getting started
|
|
|
|
|
|
|
|
|
|
To get started, you may run the following
|
|
|
|
|
|
2021-10-04 22:18:40 +03:00
|
|
|
|
$ go install golang.org/dl/gotip@latest
|
2021-09-22 21:43:43 +03:00
|
|
|
|
$ gotip download
|
2021-06-02 22:39:51 +03:00
|
|
|
|
|
2021-09-22 21:43:43 +03:00
|
|
|
|
This builds the Go toolchain from the master branch. After running this, `gotip`
|
|
|
|
|
can act as a drop-in replacement for the `go` command. You can now run commands
|
|
|
|
|
like
|
2021-06-02 22:39:51 +03:00
|
|
|
|
|
2021-09-22 21:43:43 +03:00
|
|
|
|
$ gotip test -fuzz=Fuzz
|
2021-06-02 22:39:51 +03:00
|
|
|
|
|
2021-11-12 00:29:34 +03:00
|
|
|
|
## Writing a fuzz test
|
2021-06-02 22:39:51 +03:00
|
|
|
|
|
2021-11-12 00:29:34 +03:00
|
|
|
|
A fuzz test must be in a \*\_test.go file as a function in the form `FuzzXxx`.
|
2021-06-02 22:39:51 +03:00
|
|
|
|
This function must be passed a` *testing.F` argument, much like a `*testing.T`
|
|
|
|
|
argument is passed to a `TestXxx` function.
|
|
|
|
|
|
2021-11-12 00:29:34 +03:00
|
|
|
|
Below is an example of a fuzz test that’s testing the behavior of the [net/url
|
2021-06-02 22:39:51 +03:00
|
|
|
|
package](https://pkg.go.dev/net/url#ParseQuery).
|
|
|
|
|
|
2021-10-04 22:18:40 +03:00
|
|
|
|
//go:build go1.18
|
|
|
|
|
// +build go1.18
|
2021-06-02 22:39:51 +03:00
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
2021-09-22 21:43:43 +03:00
|
|
|
|
You can read more about fuzzing at pkg.go.dev, including [an overview
|
|
|
|
|
of fuzzing with Go](https://pkg.go.dev/testing@master#hdr-Fuzzing) and the
|
|
|
|
|
[godoc for the new `testing.F` type](https://pkg.go.dev/testing@master#F).
|
2021-06-02 22:39:51 +03:00
|
|
|
|
|
|
|
|
|
## Expectations
|
|
|
|
|
|
2021-09-22 21:43:43 +03:00
|
|
|
|
This is a new feature that's still in beta, so you should expect some bugs
|
2021-06-02 22:39:51 +03:00
|
|
|
|
and an incomplete feature set. Check the [issue tracker for issues labelled
|
|
|
|
|
“fuzz”](https://github.com/golang/go/issues?q=is%3Aopen+is%3Aissue+label%3Afuzz)
|
|
|
|
|
to stay up-to-date on existing bugs and missing features.
|
|
|
|
|
|
|
|
|
|
Please be aware that fuzzing can consume a lot of memory and may impact your
|
|
|
|
|
machine’s performance while it runs. `go test -fuzz` defaults to running fuzzing
|
|
|
|
|
in `$GOMAXPROCS` processes in parallel. You may lower the number of processes
|
|
|
|
|
used while fuzzing by explicitly setting the `-parallel` flag with `go test`.
|
|
|
|
|
Read the documentation for the `go test` command by running `gotip help
|
|
|
|
|
testflag` if you want more information.
|
|
|
|
|
|
|
|
|
|
Also be aware that the fuzzing engine writes values that expand test coverage to
|
|
|
|
|
a fuzz cache directory within `$GOCACHE/fuzz` while it runs. There is currently
|
|
|
|
|
no limit to the number of files or total bytes that may be written to the fuzz
|
2022-06-12 21:19:30 +03:00
|
|
|
|
cache, so it may occupy a large amount of storage (i.e. several GBs). You can
|
2021-06-02 22:39:51 +03:00
|
|
|
|
clear the fuzz cache by running `gotip clean -fuzzcache`.
|
|
|
|
|
|
|
|
|
|
## What’s next?
|
|
|
|
|
|
2021-09-22 21:43:43 +03:00
|
|
|
|
This feature will become available starting in Go 1.18.
|
2021-06-02 22:39:51 +03:00
|
|
|
|
|
2021-09-22 21:43:43 +03:00
|
|
|
|
If you experience any problems or have an idea for a feature, please [file an
|
2023-12-18 23:16:58 +03:00
|
|
|
|
issue](/issue/new/?&labels=fuzz).
|
2021-06-02 22:39:51 +03:00
|
|
|
|
|
|
|
|
|
For discussion and general feedback about the feature, you can also participate
|
|
|
|
|
in the [#fuzzing channel](https://gophers.slack.com/archives/CH5KV1AKE) in
|
|
|
|
|
Gophers Slack.
|
|
|
|
|
|
2021-08-03 07:54:24 +03:00
|
|
|
|
Happy fuzzing!
|