VNX-835: Loop with Unreachable Exit Condition ('Infinite Loop')
Detects while loops whose condition compares a variable with a bound when the body never changes either side and has no break, return or throw, so the loop can never end. Java, JavaScript/TypeScript and Python.
| Field | Value |
|---|---|
| Rule ID | VNX-835 |
| Severity | Medium |
| SARIF level | warning |
| Kind | sast |
| Languages | Java, JavaScript / TypeScript, Python |
| CWE | CWE-835 |
| CAPEC | CAPEC-66 |
| ATT&CK | T1190 |
| CWSS vector | CWSS:1.0/TI:M/AP:RU/AL:S/IC:N/FC:LT/RP:RU/RL:S/AV:L/AS:N/IN:A/SC:A/BI:M/DI:H/EX:M/EC:N/P:C |
| Tags | infinite-loop denial-of-service cwe-835 |
| Source | internal/sast/rules/vnx-835.rego |
Overview
VNX-835 maps to CWE-835: Loop with Unreachable Exit Condition (‘Infinite Loop’). A loop such as while (i < count) ends only when something in its body moves i or count. When the body forgets to, the condition that held on entry holds forever: the thread spins, the request never completes, and an attacker who can reach the loop can exhaust CPU.
The rule reads each while loop whose condition is variable <op> bound (<, <=, >, >=, !=) and reports it when the body:
- never assigns, increments or rebinds the variable (
i++,++i,i += 1,i = next(i), tuple assignment, walrus,for i in ...), - never changes the bound (a plain variable assigned, or the collection behind
len(q),q.size(),items.lengthmutated through a method call), and - has no
break,return,throw,raise,yieldor exit call.
What Gets Flagged
int i = 0;
while (i < count) { // FLAGGED: i never advances
total += values[i];
}
while pos < end: # FLAGGED: pos never advances
ch = text[pos]
handle(ch)
What Is Not Flagged
- Deliberate infinite loops (
while True:,while (true),for (;;)), which are almost always server or worker loops. do { ... } while (i < n);loops.- Loops that advance the variable in any form, or that leave by
break,returnorthrow. - Conditions on fields or method calls alone, bodies longer than 60 lines, and the pattern in comments or string literals.
Remediation
Advance the loop variable on every path through the body (or use a for loop that does it in the header), and give any loop that waits on external state a timeout or a maximum iteration count.
References
Suppressing this rule
Put a nosec comment on the line, or on line 1 to cover the whole file. Use the comment marker of the file’s language (#, //, -- or ;):
# nosec vnx-835
// nosec vnx-835
Or record an ignore rule: vulnetix ignore add --rule vnx-835 --reason "...". See Suppressing findings.