beacon-fuzz
Open-source fuzzing framework for Ethereum 2.0 (Eth2) Phase0 implementations. Maintained by Sigma Prime for the Ethereum Foundation.
Community Fuzzing
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.
Overview
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.
Architecture overview
The following diagram describes the current architecture of beacon-fuzz
:
eth2fuzz
- Coverage Guided Fuzzer
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.
eth2diff
- Replaying Samples Across Implementations
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
).
beaconfuzz_v2
- Differential Fuzzing with FFI Bindings
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.
Implementations
- Lighthouse (Rust)
- Lodestar (JavaScript)
- Nimbus (Nim)
- Prysm (Go)
- Teku (Java)
Operational Fuzz Targets
This project currently focuses on core state transition functions. All fuzzing targets currently use the "mainnet" config.
attestation
-process_attestation
attester_slashing
-process_attester_slashing
block
-state_transition
block_header
-process_block_header
deposit
-process_deposit
proposer_slashing
-process_proposer_slashing
voluntary_exit
-process_voluntary_exit
Corpora
See corpora for examples and explanation of structure.
Usage
Please refer to each tool's README
for detailed instructions:
Progress and Roadmap
- 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.
Contributing
Use pre-commit
$ pre-commit install
(see also .pre-commit-config.yaml)
Trophies
The fuzzing tools developed as part of this project (eth2fuzz
, eth2diff
and beaconfuzz_v2
) helped identify the following bugs inside eth2 clients.
Nimbus
- Nimbus:
process_attestation
missing index validation fixed - Nimbus (Consensus Bug):
process_deposit
not validating merkle proofs fixed - Nimbus:
ncli_pretty
Deposit
SSZ parsingAssertionError
fixed - Nimbus:
ncli_pretty
Bytes ReaderIndexError
decodingBeaconState
with empty container fixed - Nimbus:
ncli_pretty
Bytes ReaderIndexError
decodingBeaconState
with variable list reporting 0 length fixed - Nimbus:
ncli_transition
out of memory segfault duringprocess_final_updates
fixed - Nimbus:
ncli_transition
AssertionError
due to inconsistent aggregation bits and committee length when passed invalidBeaconState
andBeaconBlock
(See 1) fixed - Nimbus:
ncli
IndexError
decoding 0-byte SSZ BitList fixed - Nimbus:
IndexError
duringAttesterSlashing
processing fixed - Nimbus: Integer Underflow/overflow in
ProposerSlashing
processing fixed (thanks @Daft-Wullie for helping identify this bug!)
Trinity
Teku
- Teku: infinite loop when decoding SSZ
BitList
without "end-of-list" marker bit fixed - Teku: transition subcommand raising
IllegalArgumentException
instead of logging when passed invalid SSZ fixed - Teku: transition subcommand raising
IllegalArgumentException
instead of logging when passed invalid SSZ fixed - Teku:
IndexOutOfBoundsException
when SSZ decoding 0-byteBitList
fixed - Teku:
IndexOutOfBoundsException
when passed invalidBeaconState
and committee size is inconsistent with attestation aggregation bits. (See 1) fixed - Teku:
ArrayIndexOutOfBoundsException
inAttesterSlashing
processing fixed - Teku:
ProposerSlashing
processing spec deviation (not directly exploitable) fixed
Lighthouse
- 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
- Lodestar:
TypeError
when SSZ decoding aBlock
with invalidBigInt
parent scope fixed - Lodestar:
RangeError
when SSZ decoding an emptyBlock
container - Lodestar:
TypeError
when decoding invalidENR
string fixed - Lodestar:
TypeError: public key must be a Buffer
when decoding invalidENR
string fixed - Lodestar: memory exhaustion / OOM when parsing invalid
ENR
string fixed (thanks @Daft-Wullie for helping identify this bug!) - Lodestar:
AssertionError
inbcrypto
library when parsing invalidENR
string fixed (thanks @Buttaa for helping identify this bug!) - Lodestar: Failed assertion
val->IsArrayBufferView
when parsing invalidENR
string (thanks @cooganb and @MysticRyuujin for helping identify this bug!)
Prysm
- Prysm:
panic: runtime error: slice bounds out of range
when parsing SSZ container fixed - Prysm:
panic: runtime error: nil pointer dereference
when processing ProposerSlashing fixed - Prysm (Consensus Bug): Missing validation of attestation indices in batch attestation processing fixed
- Prysm:
panic: runtime error: slice bounds out of range
when parsingSimpleMessage
- Prysm:
ProposerSlashing
processing 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
BLS
- 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.
License
MIT - see LICENSE