For the complete documentation index, see llms.txt. This page is also available as Markdown.

76546 bc low memory leak in consensus through malicious discv5 peer recommendations because of eager dialing leading to rollup node crash

Submitted on May 4th 2026 at 19:52:32 UTC by @Franfran for Audit Comp | Base Azul

  • Report ID: #76546

  • Report Type: Blockchain/DLT

  • Report severity: Low

  • Target: https://github.com/base/base/tree/v0.8.0-rc.28

  • Impacts:

    • RPC API crash affecting programs with greater than or equal to 25% of the market capitalization on top of the respective layer

Description

Brief/Intro

The rollup node implements the discv5 protocol and reacts to discovered ENRs. The problem is that the node directly attempts to dial any of these and add it to the connection gater to track the connection state. This opens multiple attack scenarios:

  1. Targeted DDOS of victim nodes

  2. Memory leak in the connection gater

While (1.) has been partially mitigated by #2432 which enforces connection limits at the libp2p layer, the memory leak is still exploitable.

Vulnerability Details

There is a memory leak in the connection_gater. But we can accelerate how fast it's going to grow by creating a bunch of malicious discv5 clients.

When we receive an ENR from the discv5 library, it's passed to the enr_sender channel and then we call the dial_multiaddr eagerly without any kind of filtering done first.

At the end of the function, we call the connection_gater with the dialing function

And then we call the actual dial function from the libp2p swarm:

The problem is that the dialing function adds a new entry to the self.current_dials as well as the self.connectedness, while remove_dial (which is called in case of libp2p dial function error) only clears the entry in the current_dials function.

But there is even worse. If the dial returned an Ok(..), we call dialed which doesn't edit the connectedness or current_dials, but it adds a new entry to the self.dialed_peers!

While having a quick look at the libp2p dial function, it seems like dial errors are only (roughly) returned when the connection limits are hit. The memory leak is attained more easily when the dial returns an Ok(..) but it can still be triggered if the function returns an error.

Impact Details

Base nodes are all dependent on the rollup node, which depends on the network actor, which is the component that features this discovery protocol discv5.

Attackers can spin up many instances of malicious discovery nodes which will pollute the storage of honest nodes, and make them crash in the long run since they may go out of memory, which is going to introduce a lot of instability on the network, and create DOS (Denial of Service) attacks which is a liveness threat to the network.

Proof of Concept

This proof of concept shows that the attack vector is real, but has not really been optimized to make it blow up fast because of time constraint (this is the last hour before the contest ends). Further analysis of the discv5 library and of the integration test could certainly find some ways for malicious peers to send ENRs at a higher throughput.

Changes has to be done to the discv5 libraries in order for this to work, but some explanations regarding the attack have been given. It's still exploitable but just makes the attack easier to reproduce in a test env.

Here are the few things which have been done:

1. Modification of the discv5 library

Basically, return many garbage node when receiving the FIND_NODE request:

Then, you will have to modify the way it's imported in Cargo.toml. For instance you can import it by path.

2. Logging to make the memory leak easier to spot

3. Integration test

Spinning a bunch of consensus nodes to observe the memory leak

Change the TestNetworkBuilder implementation to create real-life-like discovery networks with ports and stuff:

Allow ENR validation to always pass. It's easy to "exploit" but would be pretty verbose to do in the discv5 library, where the malicious ENRs are built.


Run the test output

You will see the connection gater grow. After only ~15 minutes of running, we already have more than 4k entries:

Was this helpful?