fix(l1): add anti-amplification check to discv5 handle_find_node#6200
Conversation
🤖 Kimi Code ReviewSecurity Issue: Amplification Attack MitigationFile: The PR attempts to prevent amplification attacks by validating the sender's IP address matches the stored contact information. However, there's a critical flaw in the implementation:
Recommendations:
let contact = match self.peer_table.get_contact(sender_id).await? {
Some(contact) => {
if contact.ip() != sender_addr.ip() {
trace!(from = %sender_id, expected_ip = %contact.ip(), actual_ip = %sender_addr.ip(), "IP mismatch in FINDNODE");
return Ok(());
}
contact
}
None => {
trace!(from = %sender_id, "Received FINDNODE from unknown node");
return Ok(());
}
};
The approach is directionally correct for security, but the implementation needs refinement to ensure robust IP validation. Automated review by Kimi (Moonshot AI) · custom prompt |
🤖 Claude Code ReviewNow I have enough context to provide a thorough review. Let me compile my findings. PR #6200 Review: Add Anti-Amplification Check to discv5 handle_find_nodeSummaryThis PR addresses a critical security vulnerability (amplification attack vector) in the discv5 implementation by adding IP validation before responding to FINDNODE requests. The fix mirrors the existing protection in discv4. Security Assessment ✅Critical Security Fix: This properly addresses a UDP amplification attack vector where:
The implementation correctly:
Code Correctness ✅Line-by-line Analysisserver.rs:14 - Import addition is correct: peer_table::{OutMessage as PeerTableOutMessage, PeerTable, PeerTableError},Properly aliases server.rs:506 - Function signature update: sender_addr: SocketAddr,Correctly passes the sender's socket address for validation. This is already available at the call site (line 782). server.rs:516-526 - Validation logic: let contact = match self
.peer_table
.validate_contact(&sender_id, sender_addr.ip())
.await?
{
PeerTableOutMessage::Contact(contact) => *contact,
reason => {
trace!(from = %sender_id, ?reason, "Rejected FINDNODE");
return Ok(());
}
};Strengths:
Minor observation: The match arm server.rs:782-783 - Call site update: self.handle_find_node(find_node_message, sender_id, sender_addr)
.await?;Correctly passes Comparison with discv4 ✅The discv4 implementation (discv4/server.rs:454-456) uses if let Ok(contact) = self
.validate_contact(sender_public_key, sender_id, from, "FindNode")
.await
{
// ... send neighbors
}The discv5 approach is slightly cleaner because:
Rust Best Practices ✅
Performance Implications ✅
Edge Cases Considered ✅
Potential IssuesMinor: Inconsistent error handling between discv4 and discv5In discv4 (server.rs:592-623), In discv5 (server.rs:516-526), the same validation returns Impact: Low - both approaches work correctly, but discv4's approach of returning an error might provide better visibility in error metrics/logging if the server has error tracking middleware. Recommendation: Consider whether you want consistent error semantics across discv4/discv5. Current implementation is acceptable, but you might want to track validation failures in metrics. Minor: Message orderingThe PR description mentions this closes #6199. Since I cannot access the issue, ensure that:
Recommendations
ConclusionApproval: ✅ LGTM This is a critical security fix that:
The code is correct, secure, and ready to merge. The only suggestions are minor enhancements (test coverage, metrics) that could be addressed in follow-up PRs if not already present. Automated review by Claude (Anthropic) · custom prompt |
🤖 Codex Code ReviewReview summary: Change is directionally good (amplification mitigation). I don’t see critical correctness or security bugs, but there are a couple of potential behavioral regressions to confirm. Findings (ordered by severity)
Rust idioms / readability
Security / protocol
If you want, I can check the surrounding bonding logic to confirm whether dropping Next steps (optional)
Automated review by OpenAI Codex · custom prompt |
Greptile OverviewGreptile SummaryThis PR adds critical security protection against UDP amplification attacks in the discv5 protocol implementation. Key Changes:
Security Impact: Confidence Score: 5/5
|
| Filename | Overview |
|---|---|
| crates/networking/p2p/discv5/server.rs | Adds anti-amplification check to FINDNODE handler by validating sender IP matches stored contact IP before sending NODES responses |
Sequence Diagram
sequenceDiagram
participant Attacker
participant DiscV5 Server
participant Victim
participant PeerTable
Note over Attacker,Victim: BEFORE this fix (Vulnerable)
Attacker->>DiscV5 Server: FINDNODE (with spoofed source IP = Victim)
DiscV5 Server->>PeerTable: get_contact(attacker_id)
PeerTable-->>DiscV5 Server: Contact(stored IP from ENR)
DiscV5 Server->>Victim: NODES response (large packet)
Note over Victim: Receives amplified traffic!
Note over Attacker,Victim: AFTER this fix (Protected)
Attacker->>DiscV5 Server: FINDNODE (with spoofed source IP = Victim)
DiscV5 Server->>PeerTable: validate_contact(attacker_id, victim_ip)
PeerTable-->>DiscV5 Server: IpMismatch
Note over DiscV5 Server: Drops request, no response sent
Note over Victim: Protected from amplification
Last reviewed commit: 29886a8
Lines of code reportTotal lines added: Detailed view |
|
Note on honest node rejection scenarios
All three cases are consistent with how |
Motivation
Discv5's
handle_find_noderesponds tocontact.node.udp_addr()(stored IP from ENR) without any sender address validation. A malicious peer with a session could update its ENR to point to a victim IP and trigger large NODES responses sent to the victim. Discv4 already has this protection viavalidate_contact.Description
Use
validate_contactinstead ofget_contactinhandle_find_nodeto verify the sender's IP matches the stored contact IP before sending NODES responses. This prevents amplification attacks and matches the existing protection already present in discv4.Closes #6199
Checklist
cargo test -p ethrex-p2p --features experimental-discv5)