The Even Number DoS: Cooking a Blockchain with Bad Math
Vulnerability ID: GHSA-FCMM-54JP-7VF6
CVSS Score: 7.5
Published: 2023-03-21
CVE-2023-28431 is a critical Denial of Service vulnerability in Frontier, an Ethereum compatibility layer for Substrate. The issue stems from a gross miscalculation in transaction costs for a cryptographic precompile. A specific mathematical operation, modular exponentiation, is dramatically slower when using even numbers as a modulus due to an underlying library's implementation. Frontier failed to charge extra for this slow path, allowing an attacker to submit cheap transactions that consume massive amounts of computational power, effectively grinding the entire network to a halt for pennies on the dollar.
TL;DR
A math function in Frontier's Ethereum layer is secretly 20x slower for even numbers than odd ones, but the gas fee was the same. Attackers could spam cheap transactions using even numbers to trigger this slow path, causing a Denial of Service and potentially halting the blockchain.
⚠️ Exploit Status: POC
Technical Details
- CWE ID: CWE-682: Incorrect Calculation
- Attack Vector: Network
- Attack Complexity: Low
- Privileges Required: None
- CVSS v3.1 Score: 7.5 (High)
- EPSS Score: 0.25% (0.00249)
- Impact: Denial of Service
- Exploit Status: Proof-of-Concept
Affected Systems
- Frontier (Ethereum compatibility layer for Substrate)
-
Frontier: All versions before the inclusion of commit 5af12e94d7dfc8a0208a290643a800f55de7b219 (Fixed in:
Not specified, but patched in commit 5af12e94d7dfc8a0208a290643a800f55de7b219)
Code Analysis
Commit: 5af12e9
Increase modexp gas cost when mod is even (#1017)
--- a/frame/evm/precompile/modexp/src/lib.rs
+++ b/frame/evm/precompile/modexp/src/lib.rs
@@ -23,7 +23,7 @@
extern crate alloc;
use alloc::{vec, vec::Vec};
use core::cmp::max;
-use num::{BigUint, FromPrimitive, One, ToPrimitive, Zero};
+use num::{BigUint, FromPrimitive, Integer, One, ToPrimitive, Zero};
use fp_evm::{
ExitError, ExitSucceed, Precompile, PrecompileFailure, PrecompileHandle, PrecompileOutput,
@@ -41,6 +41,7 @@
mod_length: u64,
exponent: &BigUint,
exponent_bytes: &[u8],
+ mod_is_even: bool,
) -> u64 {
fn calculate_multiplication_complexity(base_length: u64, mod_length: u64) -> u64 {
let max_length = max(base_length, mod_length);
@@ -91,6 +92,7 @@
MIN_GAS_COST,
multiplication_complexity * iteration_count / 3,
)
+ .saturating_mul(if mod_is_even { 20 } else { 1 })
}
/// Copy bytes from input to target.
@@ -196,7 +198,13 @@
let modulus = BigUint::from_bytes_be(&mod_buf);
// do our gas accounting
- let gas_cost = calculate_gas_cost(base_len as u64, mod_len as u64, &exponent, &exp_buf);
+ let gas_cost = calculate_gas_cost(
+ base_len as u64,
+ mod_len as u64,
+ &exponent,
+ &exp_buf,
+ modulus.is_even(),
+ );
handle.record_cost(gas_cost)?;
Mitigation Strategies
- Apply the patch from Pull Request #1017, which increases the gas cost for
modexpoperations with even moduli by a factor of 20. - Monitor on-chain network metrics, such as block processing times and validator CPU usage, for anomalies that could indicate an attack is underway.
- For chains that have not yet upgraded, consider temporarily disabling the modexp precompile if it is not critical for deployed applications.
Remediation Steps:
- Identify all nodes running a vulnerable version of Frontier.
- Upgrade your Frontier instance to a version that includes the fix from commit
5af12e94d7dfc8a0208a290643a800f55de7b219. - After upgrading, monitor the network to ensure stability and that gas costs for
modexpcalls are being calculated correctly.
References
- GitHub Advisory: Frontier's modexp precompile is slow for even modulus
- Fix PR: Increase modexp gas cost when mod is even
- Fix Commit: Increase modexp gas cost when mod is even
- NVD Entry for CVE-2023-28431
Read the full report for GHSA-FCMM-54JP-7VF6 on our website for more details including interactive diagrams and full exploit analysis.
Top comments (0)