Skip to content

VNX-1254: Incorrect Comparison Logic Granularity

A secret (a MAC, HMAC, signature, digest, hash, token, key, password, OTP, nonce or session value) is compared one element at a time in a Java loop that returns false at the first mismatch, so the comparison is performed in steps and its running time reveals how many leading bytes or characters of a forged value are correct (the software form of CWE-1254). Reported: inside a for/while loop, if (a[i] != b[i]) or if (a.charAt(i) != b.charAt(i)) followed by return false on the same line or the next code line, when the compared names or the enclosing method's signature name a secret. Not reported: an accumulate-and-test loop (diff |= a[i] ^ b[i]), MessageDigest.isEqual, a loop that returns the index of the first difference, the same loop over values whose names and method do not say they are secret, and comments. Whole-value comparisons with equals/Arrays.equals/== are reported by VNX-CRYPTO-008 and VNX-385.

Updated 02 Nov 2026Checked against cli@de9b52a
Field Value
Rule ID VNX-1254
Severity Low
SARIF level note
Kind sast
Languages Java
CWE CWE-1254
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 timing comparison early-exit java cwe-1254
Source internal/sast/rules/vnx-1254.rego

Overview

VNX-1254 maps to CWE-1254: Incorrect Comparison Logic Granularity.

Why This Matters

A loop that compares a MAC, signature or token one element at a time and returns at the first mismatch takes longer the more leading bytes are right. By timing many requests an attacker can recover a valid value byte by byte.

What Gets Flagged

for (int i = 0; i < expectedMac.length; i++) {
    if (expectedMac[i] != providedMac[i]) return false;
}

for (int i = 0; i < storedToken.length(); i++) {
    if (storedToken.charAt(i) != presented.charAt(i)) {
        return false;
    }
}

Not flagged: diff |= a[i] ^ b[i] followed by one test, MessageDigest.isEqual(a, b), loops over values that are not secrets.

Remediation

  1. Compare secrets with MessageDigest.isEqual(expected, actual).
  2. If you must write the loop, accumulate differences over the whole length and test once at the end.

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-1254
// nosec vnx-1254

Or record an ignore rule: vulnetix ignore add --rule vnx-1254 --reason "...". See Suppressing findings.

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