no-unchecked-loop-condition
Detects unchecked loop conditions that could cause DoS. This rule is part of [`eslint-plugin-secure-coding`](https://www.npmjs.com/package/eslint-plugin-secure-
Keywords: unchecked loop, CWE-400, CWE-835, infinite loop, DoS, security
Detects unchecked loop conditions that could cause DoS. This rule is part of eslint-plugin-secure-coding.
💼 This rule is set to error in the recommended config.
Quick Summary
| Aspect | Details |
|---|---|
| CWE Reference | CWE-400 (Uncontrolled Resource Consumption), CWE-835 (Infinite Loop) |
| Severity | High (CVSS 7.5) |
| Auto-Fix | 💡 Suggestions available |
| Category | Buffer, Memory & DoS |
Vulnerability and Risk
Vulnerability: Unchecked loop conditions allow loops to execute potentially indefinitely or for an excessive number of iterations, often driven by user input.
Risk: An attacker can provide input that causes the loop to run for a very long time or infinite times, consuming all available CPU or memory resources (Denial of Service - DoS), making the application unresponsive for legitimate users.
Rule Details
Loops with unchecked conditions can cause denial of service by consuming excessive CPU time or memory. This includes:
- Infinite loops without termination
- Loops with user-controlled bounds
- Recursion without depth limits
- Missing timeout protections
Why This Matters
| Issue | Impact | Solution |
|---|---|---|
| 🔄 Infinite Loop | Service unavailable | Add termination conditions |
| ⏱️ CPU Exhaustion | Performance degradation | Limit iterations |
| 💾 Memory Exhaustion | Application crash | Add timeout protection |
Examples
❌ Incorrect
// Infinite loop
while (true) {
processItem();
}
// User-controlled loop bound
const iterations = parseInt(req.query.count);
for (let i = 0; i < iterations; i++) {
doWork(); // Could run billions of times!
}
// No termination condition
let node = head;
while (node) {
process(node);
node = node.next; // Circular reference = infinite loop
}
// Unbounded recursion
function recurse(data) {
return recurse(data.child);
}✅ Correct
// While loop with break condition
let attempts = 0;
const MAX_ATTEMPTS = 100;
while (true) {
if (processItem() || attempts++ >= MAX_ATTEMPTS) {
break;
}
}
// Limit user-controlled iterations
const MAX_ITERATIONS = 1000;
const iterations = Math.min(parseInt(req.query.count) || 0, MAX_ITERATIONS);
for (let i = 0; i < iterations; i++) {
doWork();
}
// Cycle detection
const visited = new Set();
let node = head;
while (node && !visited.has(node)) {
visited.add(node);
process(node);
node = node.next;
}
// Bounded recursion
function recurse(data, depth = 0, maxDepth = 100) {
if (depth >= maxDepth) return null;
return recurse(data.child, depth + 1, maxDepth);
}Configuration
{
rules: {
'secure-coding/no-unchecked-loop-condition': ['error', {
maxStaticIterations: 10000,
userInputVariables: ['req', 'request', 'input'],
allowWhileTrueWithBreak: true,
maxRecursionDepth: 100
}]
}
}Options
| Option | Type | Default | Description |
|---|---|---|---|
maxStaticIterations | number | 10000 | Maximum allowed static iterations |
userInputVariables | string[] | ['req', 'request'] | User input variable patterns |
allowWhileTrueWithBreak | boolean | true | Allow while(true) with break |
maxRecursionDepth | number | 100 | Maximum recursion depth |
Error Message Format
The rule provides LLM-optimized error messages (Compact 2-line format) with actionable security guidance:
🔒 CWE-400 OWASP:A06 CVSS:7.5 | Uncontrolled Resource Consumption (ReDoS) detected | HIGH
Fix: Review and apply the recommended fix | https://owasp.org/Top10/A06_2021/Message Components
| Component | Purpose | Example |
|---|---|---|
| Risk Standards | Security benchmarks | CWE-400 OWASP:A06 CVSS:7.5 |
| Issue Description | Specific vulnerability | Uncontrolled Resource Consumption (ReDoS) detected |
| Severity & Compliance | Impact assessment | HIGH |
| Fix Instruction | Actionable remediation | Follow the remediation steps below |
| Technical Truth | Official reference | OWASP Top 10 |
Known False Negatives
The following patterns are not detected due to static analysis limitations:
Values from Variables
Why: Values stored in variables are not traced.
// ❌ NOT DETECTED - Value from variable
const value = userInput;
dangerousOperation(value);Mitigation: Validate all user inputs.
Wrapper Functions
Why: Custom wrappers not recognized.
// ❌ NOT DETECTED - Wrapper
myWrapper(userInput); // Uses dangerous API internallyMitigation: Apply rule to wrapper implementations.
Dynamic Invocation
Why: Dynamic calls not analyzed.
// ❌ NOT DETECTED - Dynamic
obj[method](userInput);Mitigation: Avoid dynamic method invocation.
Further Reading
- CWE-400 - Uncontrolled resource consumption
- CWE-835 - Loop with unreachable exit condition
- OWASP DoS - DoS prevention
Related Rules
no-unlimited-resource-allocation- Unbounded allocationsno-redos-vulnerable-regex- ReDoS patterns