Fuzz targets, seed corpora, and developer tooling for curl and libcurl. This repository supplies the harnesses used by curl's OSS-Fuzz project.
Documentation · Corpus decoder · Reproducing findings · Benchmarking
| Family | Purpose | Seed source |
|---|---|---|
Legacy curl_fuzzer and protocol variants |
Protocol-specific libcurl transfers driven by the established TLV format | corpora/<target>/ |
Structured curl_fuzzer_proto* |
Protobuf scenarios with target-specific policies and in-process protocol peers | scenarios/curl_fuzzer_proto/ |
Direct fuzz_* targets |
Focused fuzzing of URL, buffer queue, DoH, and netrc parsing | corpora/<target>/ |
The conditional list in scripts/fuzz_targets is the
source of truth for targets packaged for OSS-Fuzz. Structured targets are not
built for i386, and some TLS and HTTP/3 variants are omitted from
MemorySanitizer builds.
The primary local workflow targets Linux and requires Bash, Clang, CMake 3.24 or newer, Python 3, a build tool such as Ninja or Make, and network access for the initial dependency build.
Build all targets against the latest curl source:
./mainline.shUse -c to build a local curl checkout, or -t to build one target:
./mainline.sh -c /path/to/curl
./mainline.sh -t curl_fuzzer_httpThe default AddressSanitizer build creates standalone replay binaries under
build/ and runs the CTest suite. A binary accepts either individual inputs or
directories:
FUZZ_VERBOSE=1 ./build/curl_fuzzer_http \
corpora/curl_fuzzer_http/test_url_http
./build/curl_fuzzer_http corpora/curl_fuzzer_http/These standalone binaries replay inputs; they do not perform mutation fuzzing. See the local fuzzing guide for the OSS-Fuzz workflow and sanitizer options.
The Python package requires Python 3.10 or newer. With
uv:
uv sync
uv run read_corpus corpora/curl_fuzzer_http/test_url_httpOr use a conventional virtual environment:
python3 -m venv .venv
. .venv/bin/activate
python -m pip install -e .
read_corpus corpora/curl_fuzzer_http/test_url_httpUseful commands include:
read_corpusfor legacy TLV inputs.read_proto_corpusfor binary protobuf scenarios; named fields requireprotoc, but do not require a prior build from a source checkout.generate_corpusfor legacy TLV seeds.tlv_to_protofor converting legacy HTTP corpus entries to textproto.generate_decoder_htmlfor the standalone browser decoder for legacy TLV and protobufScenarioinputs. Runnpm ci --ignore-scriptsonce before building it so the pinned protobuf.js runtime can be bundled into the page.
Each command supports --help. The complete list of installed entry points is
in pyproject.toml.
Download the public OSS-Fuzz corpora for every currently supported target:
./scripts/download_public_corpus.shInputs are extracted to ossfuzz_corpus/<target>/. Existing non-empty target
directories are retained; pass -f to refresh them. Missing public corpora are
reported and skipped because newly added targets may not have one yet.
For legacy targets, checked-in binary seeds live in corpora/. For structured
targets, checked-in textproto files under scenarios/ are the source of truth;
CMake generates their binary corpus entries in the build tree.
Build coverage-instrumented targets, replay local and downloaded corpora, and produce text and HTML reports with:
./codecoverage.shThe reports are written to:
build-coverage/coverage/summary.txtbuild-coverage/coverage/html/index.html
Pass -c /path/to/curl to cover a local curl checkout. The manual Coverage
GitHub Actions workflow publishes the same reports and reuses a public-corpus
cache keyed by ISO week.
Install the Python test dependencies and run the repository checks with:
uv sync --extra python-tests
uv run pytest tests/test_*.py
./lint.shContributor documentation for the legacy and structured harnesses is in the documentation site. See REPRODUCING.md for crash investigation and BENCHMARKING.md for controlled performance and source coverage comparisons.
curl-fuzzer is distributed under the curl license. See LICENSE.