Safeguard
Application Security•

CWE-1095 Loop Condition Value Updated Inside the Loop

CWE-1095 is a loop whose exit condition depends on a value that the loop body changes. It is easy to misread, which is where off by one and infinite loop bugs come from.

Safeguard Security Team
2 min read

CWE-1095, Loop Condition Value Update within the Loop, describes a loop whose control flow condition is based on a value that is updated within the body of the loop.

MITRE marks it as a quality issue with no direct security implications and prohibits it for mapping real vulnerabilities. It earns a place in a secure coding guide because it is a classic home for logic errors.

How it happens

A standard counted loop updates its counter in the header, so you read the whole rule in one line. Here the update is hidden in the body, sometimes in only one branch.

/* Smell: the bound changes while the loop runs */
size_t n = count_items(list);
for (size_t i = 0; i < n; i++) {
    if (should_drop(list[i])) {
        remove_item(list, i);
        n--;            /* condition value changes mid loop */
    }
}

This version also skips the element that slides into position i after a removal. Readers have to simulate the loop to see that.

/* Clearer: build a new result and leave the bound alone */
size_t out = 0;
for (size_t i = 0; i < n; i++) {
    if (!should_drop(list[i])) {
        list[out++] = list[i];
    }
}
n = out;

What an attacker gains

Nothing directly. MITRE lists reduced maintainability and increased analytical complexity. The indirect risk is that loops that are hard to read are where off by one errors, skipped checks and unbounded iteration live, and some of those become real vulnerabilities in other categories.

How to find it

  • Search for loops where the variable in the condition is assigned inside the body.
  • Static analysis tools and linters often have a rule for modifying loop bounds.
  • Test with empty input, one item, and inputs where every item and no item matches.

How to fix it

  1. Prefer loops whose bound is fixed before the loop starts.
  2. Use filter and map style operations, or build a new collection instead of editing one in place.
  3. If the bound must change, comment why, and test the edge cases.
  4. Iterate backward when removing items by index.

Quick check

What bug does the in loop removal example contain?

After removing the item at index i, the next item shifts into that position, but the loop moves on and never examines it.

Sources

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.