Full Report
The Ethereum Virtual Machine (EVM) has EIPs for various large or VM breaking changing. At some specific point, these changes are made to the VM and are there until some other change is made. When creating a new version of the EVM, the EIPs are based upon the block number. These changes are typically for gas things and opcode changes. However, the merge upgrade can be enabled even with older EIPs disabled. This desync in programmatic expectations is the root cause of the bug. EIP2929 has a wrapper function that does some changing on the gas calculations. First, the oldCalculator() is called to get the raw price of gas. If the account is cold (hasn't been accessed in the TX yet), there's a 2500 extra fee. Theoretically, the operation of gas + coldCost could overflow, resulting in a lot less gas than necessary being charged. The gasCall() function calculates the cost of allocating the specific amount of memory, with a maximum of 128GB. There are some other gas operations in this area being calculated, with one of them overflowing if it occurs. So, the goal here is to get the gas + coldCost to overflow while not overflowing the checked overflow in the function above that. If this was possible, then the returned gas would be super small, resulting in way too much resources being consumed. What's the actual consequence? Making this call 5 times is taking up an absurd amount of RAM, which results in the node crashing. This only needs to be an eth_call on an exposed RPC node to trigger this. It just requires a very precise gas being provided to a CALL instruction via the stack to trigger this. This effected mainnet RPC providers like Infura, Alchemy, QuickNode, Flashbots and more. For whatever reason, the Ethereum foundation felt it was out of scope because it excludes RPC execution bugs from their bug bounty. Overall, an interesting post on breaking the RPC node of Ethereum. I hope to see more of this author in the future!
Analysis Summary
# Vulnerability: Geth Out-of-Order EIP Application Denial-of-Service
## CVE Details
- **CVE ID:** Not explicitly assigned (Determined "out of scope" by Ethereum Foundation bug bounty, handled as a Geth security fix).
- **CVSS Score:** N/A (Estimated High 7.5 - AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H)
- **CWE:** CWE-190: Integer Overflow or Wraparound, CWE-770: Allocation of Resources Without Limits or Throttling.
## Affected Systems
- **Products:** Go Ethereum (Geth) and derivatives (e.g., Flashbots Suave Execution Client).
- **Versions:** Geth versions from post-merge up to and including **v1.13.12**.
- **Configurations:** Nodes configured for Ethereum Mainnet with an exposed JSON-RPC interface.
## Vulnerability Description
The flaw resides in how Geth applies Ethereum Improvement Proposals (EIPs) during an `eth_call`. Specifically, it was possible to trigger a "desync" in programmatic expectations by applying EIPs out of order.
In `makeCallVariantGasCallEIP2929()`, a wrapper function calculates gas costs. If an account is "cold," an additional 2500 gas is added. Due to the out-of-order EIP application, the logic allowed for an integer overflow when adding `gas + coldCost`. If precisely timed, the overflow results in a very small returned gas value, bypassing certain checks while leading the VM to allocate excessive memory (up to 128GB). Repeated calls (approximately 5) cause the node to exhaust available RAM and crash.
## Exploitation
- **Status:** PoC confirmed; exploited against major RPC providers (Infura, Alchemy, etc.) during disclosure.
- **Complexity:** Low (Requires specific gas values provided to a `CALL` instruction via the stack).
- **Attack Vector:** Network (Remote via JSON-RPC `eth_call`).
## Impact
- **Confidentiality:** None
- **Integrity:** None
- **Availability:** High (Complete Denial of Service for the RPC node; manageable at zero-cost to the attacker).
## Remediation
### Patches
- **Geth v1.13.13 (Alsages):** Updates `makeCallVariantGasCallEIP2929()` to use `math.SafeAdd()` and tightens logic for activating Merge-related upgrades.
- **Suave Execution Client:** Patched following notification.
### Workarounds
- **Restrict RPC Access:** Do not expose JSON-RPC ports to the public internet without authentication or a firewall.
- **Filter Requests:** Disable or rate-limit `eth_call` and `eth_estimateGas`.
- **Block Overrides:** Filter RPC requests that contain block overrides, though this is difficult to implement without custom middleware.
## Detection
- **Indicators of Compromise:** Unexpected crashing of the Geth process (`geth` service restarts) preceded by several resource-intensive `eth_call` requests in the logs.
- **Detection Methods:** Monitor for high memory usage spikes correlated with RPC activity. Version scanning via `web3_clientVersion` can identify if a node is running a vulnerable version (<= v1.13.12).
## References
- **Geth Release:** hxxps[://]github[.]com/ethereum/go-ethereum/releases/tag/v1.13.13
- **Geth PR Fix:** hxxps[://]github[.]com/ethereum/go-ethereum/pull/29023
- **Original Research:** hxxps[://]iosiro[.]com/blog/geth-out-of-order-eip-application-denial-of-service