Fuzzing joinmarket-ng
Differential fuzzing
Differential fuzzing is a fuzzing strategy where two or more similar implementations are provided with the same input and the outputs are compared to find discrepancies.
I added some fuzzing harnesses in joinmarket-ng and used differential fuzzing to find bugs. Reference joinmarket implementation and python-bitcoinlib were used to find discrepancies in the code.
It is still a work in progress but I wanted to share the code and initial results.
Fuzzing branch: https://github.com/1440000bytes/joinmarket-ng/tree/feat/fuzzing-setup
Docs: https://github.com/1440000bytes/joinmarket-ng/blob/feat/fuzzing-setup/docs/technical/fuzzing.md
Running the fuzzers locally
Ensure you have Python 3.11+ and the required modules.
For differential fuzzing, you also need the legacy JoinMarket implementation checked out inside your system path, commonly /tmp/joinmarket-clientserver.
Atheris acts as both a library and an execution engine. You can run individual harnesses from the repository root:
# Set your PYTHONPATH to include the local NG components and the legacy reference
export PYTHONPATH=$(pwd)/jmcore/src:$(pwd)/jmwallet/src:$(pwd)/jmwalletd/src:$(pwd)/maker/src:$(pwd)/taker/src:/tmp/joinmarket-clientserver/src
# Run a specific harness for a set period (e.g., 60 seconds)
python3.11 fuzz/harnesses/fuzz_diff_serialization.py -max_total_time=60Coverage-guided fuzzers perform best when seeded with a corpus of valid inputs. The fuzz/corpus directory contains seeded data for things like transactions and protocol commands.
python3.11 fuzz/harnesses/fuzz_tx_diff.py -max_total_time=120 fuzz/corpus/tx_parser/Bugs found with differential fuzzing:
tx verification for zero input-output, non-standard version and missing nlocktime: https://github.com/joinmarket-ng/joinmarket-ng/pull/420
tx parser value range: https://github.com/joinmarket-ng/joinmarket-ng/pull/421
utxo validation for txid and vout: https://github.com/joinmarket-ng/joinmarket-ng/pull/426
utxo validation in podle: https://github.com/joinmarket-ng/joinmarket-ng/pull/427
blacklist result mismatch: https://github.com/joinmarket-ng/joinmarket-ng/issues/428
Please let me know if you have ideas to make fuzzing better in joinmarket-ng and find more bugs.




