#38902 [BC-Low] No check on the maximum size of the encoded ENR on ENR_RESPONSE packet

Submitted on Jan 17th 2025 at 13:39:03 UTC by @Franfran for Attackathon | Ethereum Protocol

  • Report ID: #38902

  • Report Type: Blockchain/DLT

  • Report severity: Low

  • Target: https://github.com/hyperledger/besu

  • Impacts:

    • (Specifications) A bug in specifications with no direct impact on client implementations

Description

Brief/Intro

When asking for an Ethereum Node Record (ENR) of another node, this one should respond with a packet containing this information. It is specified that ENR should be long of at most 300 bytes but this check is missing when decoding these packets.

Vulnerability Details

In the EIP-778 defining ENR, it is stated that "The maximum encoded size of a node record is 300 bytes. Implementations should reject records larger than this size." When receiving an ENR_RESPONSE packet, the packet is first deserialized with the ENRResponsePacketData::readFrom function. This function RLP decodes the packet data from raw RLP by using the discovery library by calling its function fromBytes but this library contains a bug. Indeed, it doesn't check if the RLP-encoded packet data size exceeds 300 bytes.Here is the definition of the fromBytes function which seems to check for the size of some data not exceeding 300 bytes, but this is only checking that the value of the id in the key-value store of the ENR does not exceed 300 bytes. This seems to be a misunderstanding with the specification, that says that the RLP-encoded record should not exceed 300 bytes. To conclude, a peer can send an unexpectedly big ENR to our node when responding with the ENRResponse packet and it's going to be accepted and stored.

Impact Details

This is a drift from the specification and will make the implementation waste resources by allowing huge UDP packets of the ENRResponse as well as storing abnormally big records on disk.

References

Links added where applicable

Proof of Concept

Allow serialization or the ENR without limit check in the call to Packet.create in order to build a simple POC

Add this test


If you're worried about the patch to the writeTo making the POC possible, revert this patch and instead build the packet from the RLP data, which doesn't check the size of the ENR record as expected.

And the updated test:

Was this helpful?