fix(p2p): guard ENR address parsing against malformed TCP fields (A-1255)#24215
Draft
PhilWindle wants to merge 1 commit into
Draft
Conversation
…255)
A discovery peer could advertise a signed, same-version, UDP-contactable
ENR with a malformed TCP field (e.g. 3 bytes instead of a 2-byte port).
validateEnr only checked the aztec key + version, so discv5 emitted
enrAdded; the unguarded async onEnrAdded listener then awaited
getFullMultiaddr('tcp'), which threw RangeError, and as an async listener
the rejection was unhandled and crashed the node.
Audit of every getFullMultiaddr/getLocationMultiaddr site in p2p found
the same pattern on the bootnode's discovered listener (crashes the
bootnode) and config-provided preferredPeers parsing (aborts setup):
- Guard onEnrAdded and the bootstrap discovered listener so a parser
exception is caught, logged and the ENR dropped (no process exit).
- validateEnr rejects an ENR whose TCP multiaddr won't parse, so it's
never emitted as a full peer / re-parsed downstream. A missing TCP addr
stays allowed (those peers are skipped at dial time).
- preferredPeers ENR parsing (peer_manager, libp2p_service) skips and logs
a malformed configured ENR instead of aborting node setup.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes A-1255.
Problem
A discovery peer can advertise a signed ENR with valid
ip/udpcontact data and the expected Aztec ENR version key, but a malformedtcpfield (e.g. 3 bytes instead of a 2-byte port).DiscV5Service.validateEnronly checked the aztec key + version, so upstream discv5 accepted the session and emittedenrAdded. The unguarded asynconEnrAddedlistener then awaitedenr.getFullMultiaddr('tcp'), which throwsRangeErroron the malformed value; as an async EventEmitter listener the rejection is unhandled and the node process exits. One malformed, UDP-contactable, same-version ENR crashes any p2p-enabled node.Audit
A sweep of every
getFullMultiaddr/getLocationMultiaddrcall inp2p/srcfound the same unguarded-parse pattern in more than one place:discV5_service.tsonEnrAddedbootstrap.tsdiscoveredlistenerpeer_manager.tshandleDiscoveredPeervalidateEnrrejecting malformed-addr ENRspeer_manager.ts/libp2p_service.tspreferredPeersFix
onEnrAddedand the bootnodediscoveredlistener so a parser exception is caught, logged, and the ENR dropped — no unhandled rejection.validateEnrrejects an ENR whose TCP multiaddr won't parse, so it's never emitted as a full peer (PeerEvent.DISCOVERED) or re-parsed byhandleDiscoveredPeer. A missing TCP addr stays allowed — those peers are simply skipped at dial time; only an unparseable one is rejected.preferredPeersENR parsing skips and logs a malformed configured ENR instead of aborting node / preferred-peer setup.The self-ENR log line (
discV5_service.ts:199-200) is intentionally left unguarded — it reads our own ENR, which we build and which can't be attacker-malformed.Tests
discv5_service.test.ts: builds a same-version ENR with validip/udpand a 3-bytetcpvalue, and asserts (a)validateEnrrejects it while a valid control built from the same identity passes — isolating the TCP check — and (b)onEnrAddedresolves (no unhandled rejection, previously aRangeError) and never emitsDISCOVERED.Note:
discV5_service.tsoverlapped with the already-merged PR #24169; this branch is off the post-mergemerge-train/spartan-v5, so no conflict.