See discord explanation for more info.
Open-source fuzzing framework for Ethereum 2.0 (Eth2) Phase0 implementations. Maintained by Sigma Prime for the Ethereum Foundation.
For details on our community fuzzing initiative, please refer to the eth2fuzz README, along with this blog post.
If you would like to raise any crashes or disclose any bugs identified using this project, please contact us via email and use our PGP key to encrypt sensitive messages.
This project aims at identifying bugs and vulnerabilities on various Eth2 implementations, by leveraging three different fuzzing tools.
This is a continuation of Guido Vranken's eth2.0-fuzzing. This project and its inner workings are subject to change.
A note on terminology: "client" and "implementation" are used interchangeably here to mean a specific Eth2 implementation.
The following diagram describes the current architecture of beacon-fuzz:
The purpose of this tool is to identify crashes (i.e. panics) in Eth2 implementations. It uses multiple different fuzzing engines (AFL++, HonggFuzz, libFuzzer, etc.). By leveraging explicit code coverage, eth2fuzz allows us to flag SSZ containers that are of interest, i.e. those that trigger new code paths.
This tool leverages various state transition execution utilities (ncli, zcli, lci, etc.) that replay all samples generated from eth2fuzz. We've created dedicated Docker containers for each implementation, and one central Docker container to orchestrate the execution of eth2diff. The goal of this tool is to detect crashes and differences across all supported implementations, for any given set of inputs (BeaconState + BeaconBlock).
A differential fuzzer of Eth2.0 implementations using libfuzzer and honggfuzz.
This tool is the successor of Guido Vranken's eth2.0-fuzzing C++ project. It is developed in Rust (for ease of maintainability) and leverages Foreign Function Interfaces (FFI) bindings.
By leveraging the latest update to the libfuzzer-sys and cargo_fuzz crates, this tool is able to write fuzz targets that take well-formed instances of custom types by deriving and implementing the Arbitrary trait, which allows us to create structured inputs from raw byte buffers.
- Lighthouse (Rust)
- Lodestar (JavaScript)
- Nimbus (Nim)
- Prysm (Go)
- Teku (Java)
This project currently focuses on core state transition functions. All fuzzing targets currently use the "mainnet" config.
attestation-process_attestationattester_slashing-process_attester_slashingblock-state_transitionblock_header-process_block_headerdeposit-process_depositproposer_slashing-process_proposer_slashingvoluntary_exit-process_voluntary_exit
See corpora for examples and explanation of structure.
Please refer to each tool's README for detailed instructions:
- Development of
eth2fuzz - Development of
eth2diff - Development of
beaconfuzz_v2- Integration of Prysm
- Integration of Lighthouse
- Integration of Nimbus
- Integration of Teku
- Improved onboarding, ease of adding new targets and implementations
- Improved coverage measurements and visibility
- Structure-aware fuzzing mutations in
beaconfuzz_v2 - Deploy on dedicated production fuzzing infrastructure
The Beacon Fuzz team regularly posts updates on the Sigma Prime blog. The latest update is available here.
Use pre-commit
$ pre-commit install(see also .pre-commit-config.yaml)
The fuzzing tools developed as part of this project (eth2fuzz, eth2diff and beaconfuzz_v2) helped identify the following bugs inside eth2 clients.
- Nimbus:
process_attestationmissing index validation fixed - Nimbus (Consensus Bug):
process_depositnot validating merkle proofs fixed - Nimbus:
ncli_prettyDepositSSZ parsingAssertionErrorfixed - Nimbus:
ncli_prettyBytes ReaderIndexErrordecodingBeaconStatewith empty container fixed - Nimbus:
ncli_prettyBytes ReaderIndexErrordecodingBeaconStatewith variable list reporting 0 length fixed - Nimbus:
ncli_transitionout of memory segfault duringprocess_final_updatesfixed - Nimbus:
ncli_transitionAssertionErrordue to inconsistent aggregation bits and committee length when passed invalidBeaconStateandBeaconBlock(See 1) fixed - Nimbus:
ncliIndexErrordecoding 0-byte SSZ BitList fixed - Nimbus:
IndexErrorduringAttesterSlashingprocessing fixed - Nimbus: Integer Underflow/overflow in
ProposerSlashingprocessing fixed (thanks @Daft-Wullie for helping identify this bug!)
- Teku: infinite loop when decoding SSZ
BitListwithout "end-of-list" marker bit fixed - Teku: transition subcommand raising
IllegalArgumentExceptioninstead of logging when passed invalid SSZ fixed - Teku: transition subcommand raising
IllegalArgumentExceptioninstead of logging when passed invalid SSZ fixed - Teku:
IndexOutOfBoundsExceptionwhen SSZ decoding 0-byteBitListfixed - Teku:
IndexOutOfBoundsExceptionwhen passed invalidBeaconStateand committee size is inconsistent with attestation aggregation bits. (See 1) fixed - Teku:
ArrayIndexOutOfBoundsExceptioninAttesterSlashingprocessing fixed - Teku:
ProposerSlashingprocessing spec deviation (not directly exploitable) fixed
- Lighthouse: out-of-bounds offset in variable list SSZ decoding fixed
- Lighthouse: multiplication overflow in
compute_proposer_index(See 1) fixed - Lighthouse: ENR panic fixed
- Lighthouse: Underflow in Snappy (external dependency) fixed
- Lodestar:
TypeErrorwhen SSZ decoding aBlockwith invalidBigIntparent scope fixed - Lodestar:
RangeErrorwhen SSZ decoding an emptyBlockcontainer - Lodestar:
TypeErrorwhen decoding invalidENRstring fixed - Lodestar:
TypeError: public key must be a Bufferwhen decoding invalidENRstring fixed - Lodestar: memory exhaustion / OOM when parsing invalid
ENRstring fixed (thanks @Daft-Wullie for helping identify this bug!) - Lodestar:
AssertionErrorinbcryptolibrary when parsing invalidENRstring fixed (thanks @Buttaa for helping identify this bug!) - Lodestar: Failed assertion
val->IsArrayBufferViewwhen parsing invalidENRstring (thanks @cooganb and @MysticRyuujin for helping identify this bug!)
- Prysm:
panic: runtime error: slice bounds out of rangewhen parsing SSZ container fixed - Prysm:
panic: runtime error: nil pointer dereferencewhen processing ProposerSlashing fixed - Prysm (Consensus Bug): Missing validation of attestation indices in batch attestation processing fixed
- Prysm:
panic: runtime error: slice bounds out of rangewhen parsingSimpleMessage - Prysm:
ProposerSlashingprocessing spec deviation (not directly exploitable) fixed - Prysm (Consensus Bug): Off-by-one bug in attestation processing fixed
- Prysm (Consensus Bug): wrong epoch in proposer slashing validation fixed
- BLST: Point Decompression does not handle invalid byte lengths fixed
- BLST: Point Decompression does not enforce field points are less than field modulus fixed
1: NOTE BeaconState objects are considered trusted inputs (for the moment), so client state transition functions are not expected to handle invalid BeaconState values, for now.
MIT - see LICENSE