#37210 [BC-Insight] Missing Check of HTTP Batch Response Length

Submitted on Nov 28th 2024 at 20:53:10 UTC by @CertiK for Attackathon | Ethereum Protocol

  • Report ID: #37210

  • Report Type: Blockchain/DLT

  • Report severity: Insight

  • Target: https://github.com/ledgerwatch/erigon

  • Impacts:

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

Description

Brief/Intro

The Client.BatchCallContext in the rpc package of Ethereum client Erigon ( https://github.com/erigontech/erigon ) could be stuck due to the missing check of the HTTP batch response length in the sendBatchHTTP().

Vulnerability Details

Affected Codebase: https://github.com/erigontech/erigon/tree/v2.61.0-beta1

In the rpc package, the Client.BatchCall() is used to send all requests in a single batch, which calls the Client.BatchCallContext() to perform the batched calls, in which the Client.sendBatchHTTP() will be invoked in case that it’s an HTTP request:

https://github.com/erigontech/erigon/blob/v2.61.0-beta1/rpc/client.go#L332

As mentioned in the PR: https://github.com/ethereum/go-ethereum/pull/26064

It turns out that Client.BatchCallContext relies on the number or response messages exactly matching the number of requests. If too many responses are received, sendBatchHTTP blocks trying to send more than will fit in the channel buffer, and never yields to timeout. If too few responses are received, BatchCallContext waits for the missing responses from the empty channel, but eventually yields to timeout.

https://github.com/erigontech/erigon/blob/v2.61.0-beta1/rpc/http.go#L125

It is worth noted a similar issue has been fixed in go-ethereum by checking the message and response have same size : https://github.com/ethereum/go-ethereum/pull/26064

Impact Details

Client.BatchCall() could be stuck in case two many or too few responses are received.

References

  • https://github.com/erigontech/erigon/blob/v2.61.0-beta1

  • https://github.com/ethereum/go-ethereum/pull/26064

Proof of Concept

Proof of Concept

For simplicity, we can reuse the test from go-ethereum (https://github.com/ethereum/go-ethereum/pull/26064 ) to verify the issue:

The test hangs and does not complete.

Was this helpful?