VNX-1095: Loop Condition Value Update within the Loop
A Python for loop or Java enhanced for loop that removes, inserts or puts into the very collection it is iterating over, which skips elements, raises RuntimeError or throws ConcurrentModificationException.
| Field | Value |
|---|---|
| Rule ID | VNX-1095 |
| Severity | Low |
| SARIF level | note |
| Kind | sast |
| Languages | Python, Java |
| CWE | CWE-1095 |
| CAPEC | CAPEC-66 |
| ATT&CK | T1190 |
| CWSS vector | CWSS:1.0/TI:L/AP:RU/AL:S/IC:N/FC:LT/RP:RU/RL:S/AV:L/AS:N/IN:A/SC:A/BI:L/DI:H/EX:L/EC:N/P:L |
| Tags | loop concurrent-modification reliability cwe-1095 |
| Source | internal/sast/rules/vnx-1095.rego |
Overview
VNX-1095 maps to CWE-1095: Loop Condition Value Update within the Loop. The collection a for loop iterates over is its loop condition; changing it inside the body changes the condition while the loop runs.
- Python: inside
for x in items:(oritems.keys()/values()/items()), a call toitems.remove/pop/popitem/insert/clear/update/setdefault/add/discardordel items[...]. - Java: inside
for (T x : items)(oritems.entrySet()/keySet()/values()), a call toitems.remove/add/addAll/removeAll/retainAll/removeIf/clear/put/putAll.
Why This Matters
Removing from a Python list while iterating skips the element after each removal, so an “expire every stale session” loop leaves some stale sessions alive. Changing a dict or set raises RuntimeError. In Java the iterator throws ConcurrentModificationException on its next step, which turns a clean-up path into a crash.
Not reported: iteration over a copy (list(items), items[:], items.copy(), sorted(items), new ArrayList<>(items)), a mutation followed directly by break or return, list.append/extend (the worklist idiom), Iterator.remove(), Java files using concurrent or copy-on-write collections, and comments.
What Gets Flagged
for s in sessions:
if s.expires_at < now:
sessions.remove(s) # FLAGGED
for (Map.Entry<String, Entry> e : entries.entrySet()) {
if (e.getValue().size() > limit) {
entries.remove(e.getKey()); // FLAGGED
}
}
Remediation
- Iterate over a copy, or build a new collection (
[s for s in sessions if s.expires_at >= now]). - In Java use
Iterator.remove(),removeIf(...)orentrySet().removeIf(...). - For a confirmed false positive, add a
vulnetix-ignore: VNX-1095comment on the line.
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-1095
// nosec vnx-1095
Or record an ignore rule: vulnetix ignore add --rule vnx-1095 --reason "...". See Suppressing findings.