DoS Compute Exhaustion
Detects potential denial-of-service via unbounded compute unit consumption.
DoS Compute Exhaustion
Overview
The DoS compute exhaustion detector identifies patterns that could exhaust Solana’s compute unit budget (200K base, 1.4M maximum), causing transaction failure and enabling denial-of-service attacks. It uses CFG analysis to distinguish between bounded loops with proper termination and truly unbounded loops controlled by user input.
For remediation guidance, see DoS Compute Exhaustion Remediation.
Why This Is an Issue
Solana programs operate under strict compute unit budgets. Expensive operations such as CPI calls inside loops, dynamic allocations scaling with user input, and recursive CPI calls without depth limits can easily exhaust the budget. An attacker who can control the iteration count of a loop or the number of CPI calls can force transactions to fail, creating a denial-of-service condition that prevents legitimate users from interacting with the program.
How to Resolve
Before (Vulnerable)
// Vulnerable: unbounded loop processes user-controlled list
pub fn process_all(ctx: Context<Process>, items: Vec<Item>) -> Result<()> {
for item in items.iter() { // No upper bound on items.len()
process_item(ctx.accounts, item)?; // Each iteration uses compute
}
Ok(())
}
After (Fixed)
const MAX_ITEMS: usize = 10;
// Fixed: bounded iteration with explicit limit
pub fn process_all(ctx: Context<Process>, items: Vec<Item>) -> Result<()> {
require!(items.len() <= MAX_ITEMS, ErrorCode::TooManyItems);
for item in items.iter() {
process_item(ctx.accounts, item)?;
}
Ok(())
}
Example JSON Finding
{
"detector": "dos-compute-exhaustion",
"severity": "high",
"confidence": 0.8,
"message": "CPI call inside loop without iteration bound -- compute budget exhaustion risk",
"location": { "function": "process_all", "block": 3, "statement": 1 }
}
Detection Methodology
- Back-edge analysis: Identifies true loops via CFG back-edge detection, distinguishing bounded loops from unbounded ones.
- CPI-in-loop detection: Flags any CPI calls within loop bodies, since even bounded loops with CPI are expensive.
- User-input taint tracking: Determines whether loop bounds derive from user-controlled instruction data.
- Infinite loop detection: Identifies loops with no exit condition in the loop structure.
Limitations
False positives: Loops with complex but valid exit conditions across multiple blocks may appear unbounded. False negatives: Compute exhaustion via deeply nested arithmetic (no CPI, no loops) is not detected.
Related Detectors
- Compute Exhaustion — resource management compute budget issues
- Transaction Size DoS — unbounded account lists causing size limits
- CPI In-Loop DoS — CPI calls in loops