google/fuzzing-go-expert
Use this skill to fuzz open source Go software projects.
npx skills add https://github.com/google/oss-fuzz --skill fuzzing-go-expert
This skill provides the agent with the knowledge and tools to write, build, and
validate fuzz targets for Go projects integrated into OSS-Fuzz. Go fuzzing uses
the native Go fuzzing framework introduced in Go 1.18, which OSS-Fuzz drives
via libFuzzer under the hood using compile_native_go_fuzzer.
Go projects must use the Go base builder image:
FROM gcr.io/oss-fuzz-base/base-builder-go
Set language: go in project.yaml.
Go fuzz targets are standard Go test functions with the prefix Fuzz, placed
in _test.go files (or plain .go files that import the testing package):
package mypkg
import (
"testing"
_ "github.com/AdamKorcz/go-118-fuzz-build/testing" // required for OSS-Fuzz native fuzzing
)
func FuzzMyTarget(f *testing.F) {
// Seed corpus: add representative valid inputs so the fuzzer starts
// from a meaningful state rather than empty bytes.
f.Add([]byte("example input"))
f.Add([]byte("another seed"))
f.Fuzz(func(t *testing.T, data []byte) {
// Call into the target. Ignore expected errors; let unexpected
// panics surface as findings.
_, _ = ParseSomething(data)
})
}
The inner f.Fuzz callback signature can use typed parameters instead of
[]byte when the target expects structured input:
f.Fuzz(func(t *testing.T, s string, n int, b bool) {
_ = ProcessRecord(s, n, b)
})
Use the compile_native_go_fuzzer helper in build.sh. It takes the package
import path, the function name, and the output binary name:
# build.sh
cp $SRC/fuzz_test.go ./ # copy harness into the module if needed
printf "package mypkg\nimport _ \"github.com/AdamKorcz/go-118-fuzz-build/testing\"\n" \
> register.go # required registration shim
go mod tidy
compile_native_go_fuzzer github.com/owner/repo/pkg FuzzMyTarget fuzz_my_target
For projects with multiple packages or multiple fuzz targets repeat the call:
compile_native_go_fuzzer github.com/owner/repo/pkg1 FuzzFoo fuzz_foo
compile_native_go_fuzzer github.com/owner/repo/pkg2 FuzzBar fuzz_bar
$OUT/<fuzzer_name>_seed_corpus/ as individualfiles, or as a zip at $OUT/<fuzzer_name>_seed_corpus.zip.
$OUT/<fuzzer_name>.dict as plaintext token files.f.Add(...) in the harness — theseare compiled in and used as the initial corpus.
beats hand-picking a few files — random mutation rarely passes the parser's
early checks. See the [structured seed generation
reference](../oss-fuzz-engineer/references/structured_seed_generation.md).
serialisation/deserialisation, and any API that accepts untrusted bytes or
strings.
expected error returns. Only genuine panics and unexpected behaviour are
findings.
Go's fuzzer can mutate string, int, bool, float64, etc. directly.
global state that persists between calls.
files) belongs outside f.Fuzz(...), not inside the inner function.
f.Add(...) entries should be validrepresentative inputs so coverage grows from the start.
inside the fuzz function.
"github.com/AdamKorcz/go-118-fuzz-build/testing"` blank import is required
for OSS-Fuzz to hook into native Go fuzzing — never omit it.
Go is memory-safe, so the focus shifts from memory-corruption bugs to:
failures, stack overflows — any unrecovered panic is a crash.
valid input.
(detected by OSS-Fuzz's timeout).
instead, or vice versa.
python3 infra/helper.py build_fuzzers <project>
python3 infra/helper.py check_build <project>
python3 infra/helper.py run_fuzzer <project> <fuzzer_name> -- -max_total_time=30
missing error handling, bad seed, wrong package path).
go vet ./... and go build ./... inside the module before wrapping inan OSS-Fuzz build to catch compile errors early.
RUN git clone to COPY to avoid network round-trips.
Take google/fuzzing-go-expert from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.