2.4 KiB
go-ethereum (geth) — CWE-407 Disclosure Brief
2026-03-27 · Patch available — awaiting upstream merge
Finding
One O(n²) defect in go-ethereum's log filtering. FilterLogs in eth/filters/filter.go scans an address slice on every log entry per block, causing O(n×logs) overhead per eth_getLogs call. Patch ready for upstream review.
The Defects
geth-0001 (PATCHED — HIGH): eth/filters/filter.go
// FilterLogs — per log per block:
for _, log := range logs {
for _, addr := range addresses { // O(A) slice scan per log
if log.Address == addr {
matched = append(matched, log)
}
}
}
// O(n×logs×A) total
Address slice scan O(A) per log entry per block. For n blocks, L logs per block, A addresses in filter: O(n × L × A). Measured ratio: 357×.
Complexity Proof
For A=357 filter addresses, L logs per block:
- Per block: O(L×A) comparisons
- Fixed:
map[common.Address]struct{}→ O(L) per block - 357× measured ratio.
Impact
All go-ethereum nodes and applications using eth_getLogs with address filters — wallets, DeFi protocols, block explorers, indexers, and event monitoring services. FilterLogs is called for every log subscription and historical log query. Applications that filter across many contract addresses (DeFi aggregators, indexers like The Graph) and high-activity chains hit worst case on every block. geth is the most widely deployed Ethereum execution client.
The Fix
Replace address slice with map[common.Address]struct{}:
// Before
for _, addr := range addresses { // O(A) per log
if log.Address == addr { ... }
}
// After
// CWE-407 fix: map[common.Address]struct{} for O(1) address check instead of O(A) scan.
addrSet := make(map[common.Address]struct{}, len(addresses))
for _, addr := range addresses { addrSet[addr] = struct{}{} }
for _, log := range logs {
if _, ok := addrSet[log.Address]; ok { ... }
}
Patch
defects/geth/patch/geth-0001-filterlogs-address-map.patch
What We Ask
- Confirm receipt and assign a GitHub Security Advisory or issue reference.
- Validate the patch against your filter and log subscription test suite.
- Assess CVE eligibility — 357× overhead on every eth_getLogs call with many addresses.
- Coordinate a disclosure date — we are targeting 90 days from first contact.
Contact: see cover email. This brief is confidential until coordinated disclosure.