Memory Exhaustion in CometBFT v1.0.1 via malicious ProposalMessage leads to network-wide denial of service
Unknown
Vulnerability Details
### Summary of Impact
CometBFT v1.0.1 contains a critical memory exhaustion vulnerability that allows any peer to crash nodes with a single ~50-byte P2P message. An attacker can send a malicious `ProposalMessage` with `PartSetHeader.Total` set to `2^32-1`, causing the receiving node to immediately allocate 512 MB of memory without prior validation, resulting in an OOM kill.
The impact is complete network denial of service. For a 69-validator network (like Berachain mainnet), an attacker can halt consensus by crashing just 23 validators (34%) with only 1.15 KB of bandwidth.
Severity: HIGH/CRITICAL (depends on chain, if being validator is permissionless etc)
### Steps to Reproduce
1. Create a malicious `ProposalMessage` with `PartSetHeader.Total` set to `2^32-1` (4,294,967,295)
2. Connect to a target node running CometBFT v1.0.1 via P2P protocol
3. Send the malicious message to the target node
4. The node will immediately allocate 512 MB of memory and be terminated by the OOM killer
Vulnerable code path:
- Entry point: `internal/consensus/reactor.go:334-336` - No validation before processing
- Unvalidated allocation: `internal/consensus/reactor.go:1169` - Attacker controls Total value
- Unsafe allocation: `internal/bits/bit_array.go:31` - Unbounded memory allocation
- Validation that never executes: `internal/consensus/state.go:2075-2077` - Too late in execution flow
A second vulnerability vector exists in `InitProposalBlockParts()` at `reactor.go:1184` which may be exploitable via `NewValidBlockMessage` or other message types.
### Workarounds
No effective mitigation exists without a code patch. Operators must manually restart nodes after they crash.
### Supporting Material/References
* Proof of Concept:
```go
package main
import (
"math"
"github.com/cometbft/cometbft/types"
cmtcons "github.com/cometbft/cometbft/api/cometbft/consensus/v1"
)
func main() {
// Create malicious proposal
proposal := types.NewProposal(1, 0, -1, types.BlockID{
Hash: make([]byte, 32),
PartSetHeader: types.PartSetHeader{
Total: math.MaxUint32, // 2^32-1 = 4,294,967,295
Hash: make([]byte, 32),
},
}, nil)
proposal.Signature = []byte{0x01}
// Send to target node on port 26656
// (P2P connection and handshake code omitted for brevity)
// Result: Target node crashes within 10ms
}
```
* Affected networks include Berachain mainnet (69 validators) and potentially all blockchain networks using CometBFT v1.0.1
* Upstream v0.38.20 version correctly mitigates the issue
Actions
View on HackerOneReport Stats
- Report ID: 3510161
- State: Closed
- Substate: not-applicable
- Upvotes: 38