Safeguard
Application Security•

CWE-1023 Incomplete Comparison with Missing Factors

A comparison that skips one required factor can treat different things as equal. CWE-1023 shows how it leads to file inclusion and path access bugs, with fixes.

Safeguard Security Team
3 min read

Comparisons look simple. Are these two things the same? Is this value allowed? When the answer depends on several factors and the code checks only some of them, the result is a quiet logic bug that attackers can use.

CWE-1023 is the class weakness: the product compares entities that must consider multiple factors or characteristics, but the comparison leaves out one or more. It applies in any language.

How it happens

MITRE's first example is an equality method. Two Truck objects are meant to be equal when make, model and year match, but the code forgets the year:

// Vulnerable: year is never compared
public boolean equals(Object o) {
    if (o == null) return false;
    if (o == this) return true;
    if (!(o instanceof Truck)) return false;
    Truck t = (Truck) o;
    return this.make.equals(t.getMake()) && this.model.equals(t.getModel());
}

The fix adds the missing factor:

return this.make.equals(t.getMake())
    && this.model.equals(t.getModel())
    && this.year == t.getYear();

Security versions of the same mistake appear in the observed CVEs. CVE-2005-2782 is a PHP remote file inclusion where the application filters http and https URLs but not ftp. CVE-2014-6394 is a product that fails to prevent access to restricted directories because of a partial string comparison with a public directory.

MITRE's second example is an authentication check using strncmp with the length of the user's input, so a short or partial input can match. The comparison considered the input's length but not the stored value's.

What an attacker gains

MITRE lists integrity and access control effects: altered execution logic and bypass of protection mechanisms. An incomplete comparison can lead to operating on the wrong object or making a security decision without considering a required factor.

How to find it

MITRE suggests manual static analysis: test the comparison scheme thoroughly before production, with positive and negative tests.

  • List the factors that define equality or permission for each comparison.
  • Write tests where only one factor differs, for every factor.
  • Review denylists. A list that misses one scheme, one directory form or one encoding is an incomplete comparison.
  • Review prefix and partial matches on paths and names.

How to fix it

  1. Define the full set of factors up front and compare all of them.
  2. Prefer allow lists over denylists, so unknown cases fail closed.
  3. Compare complete values, with lengths, not prefixes of user input.
  4. For paths, resolve to a canonical form and check containment rather than string prefix.
  5. Add negative tests that vary one factor at a time.

The free in-browser scan at gold.safeguard.sh/scan can check your dependencies, with no login and up to 100 dependencies.

Quick check

Why is a denylist often an incomplete comparison?

It enumerates what to block, so any case the author forgot, like the ftp scheme in the PHP example, gets through.

What testing does MITRE recommend?

Thorough positive and negative testing of the comparison scheme before deployment.

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.