Skip to content

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.

Updated 02 Nov 2026Checked against cli@de9b52a
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: (or items.keys()/values()/items()), a call to items.remove/pop/popitem/insert/clear/update/setdefault/add/discard or del items[...].
  • Java: inside for (T x : items) (or items.entrySet()/keySet()/values()), a call to items.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

  1. Iterate over a copy, or build a new collection ([s for s in sessions if s.expires_at >= now]).
  2. In Java use Iterator.remove(), removeIf(...) or entrySet().removeIf(...).
  3. For a confirmed false positive, add a vulnetix-ignore: VNX-1095 comment 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.

Edit this pageSources: cli/internal/sast/rules/vnx-1095.rego, cli/internal/sast/docs/vnx-1095.md
esc
↑ ↓ move↵ openSearches in your browser. A key like autonomy.max or a code like threshold_required jumps straight to it.