BT

Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ

Topics

Choose your language

InfoQ Homepage News Go Gets Fuzz Testing Support in Beta

Go Gets Fuzz Testing Support in Beta

This item in japanese

The Go team has announced fuzzing support is now available for beta testing. The main goal of the project is to create a unified and end-to-end experience for developers and users of the language, including robust module support, integration with the go command, and new compiler instrumentation.

According to Google engineer Katie Hockman, author of the fuzzing design draft, this project aims to make fuzzing a first-class option for testing Go programs just as easily as it is to run unit tests.

Since fuzzing can reach edge cases which humans often miss, fuzz testing is particularly valuable for finding security exploits and vulnerabilities. Fuzz tests have historically been authored primarily by security engineers, and hackers may use similar methods to find vulnerabilities maliciously. However, writing fuzz targets needn’t be constrained to developers with security expertise.

Fuzzing was no stranger to the Go community, explains Hockman, with tools like go-fuzz and its derivative fzgo. They imposed some unnecessary overhead to developers, though, due to the need to use non-standard tools, to separate test files or build tags, to the lack of robust modules support, and so on.

The following is a Google-provided example of a fuzzing target that tests the behaviour of the net/url package:

// +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)
        }
    })
}

A fuzz target is provided in the form of a FuzzXyz function, which receives a *testing.F argument. The f.Add function can be used to populate the seed corpus, which is the user-specified set of inputs to the fuzz target. The f.Fuzz function is executed for each item in the corpus. In addition to the seed corpus, f.Fuzz also tests the inputs provided in testdata/corpus/FuzzTarget.

When the developer uses the -fuzz flag to go test, the Go fuzzing engine will run the testing function against the generated corpus, while a mutator will generate new inputs in the attempt to discover a bug or a crasher.

Go fuzzing beta is available in Go development branch. Unfortunately, there is no schedule yet for when it will be included in a stable Go release, and Hockman rules out it will land in Go 1.17.

Being in beta, Go fuzzing is not complete yet and subject to change. There are also a number of additional features that are already in the works, says Hockman, like testing multiple targets at once, supporting dictionaries, adding custom generators for the mutator, and others.

Rate this Article

Adoption
Style

BT