VNX-571: Expression is Always True
Reports C, C++, Go and Java comparisons that always hold: a size compared >= 0, an unsigned variable compared >= 0, x != A || x != B, two ranges covering every value, and an operand compared with itself (other than the NaN tests x != x and a float v == v).
| Field | Value |
|---|---|
| Rule ID | VNX-571 |
| Severity | Low |
| SARIF level | note |
| Kind | sast |
| Languages | C, C++, Go, Java |
| CWE | CWE-571 |
| 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 | always-true cwe-571 |
| Source | internal/sast/rules/vnx-571.rego |
Overview
VNX-571 maps to CWE-571: Expression is Always True. A condition that always holds never rejects anything. When it was an authorization, bounds or loop-termination check, the protection it was meant to give is not there, and a loop it controls never ends.
What Gets Flagged
- A length or size compared with zero from above:
len(items) >= 0,scopes.length >= 0,grants.size() >= 0,strlen(s) >= 0,name.size() >= 0, and0 <= sizeof(s). - An unsigned variable compared
>= 0: a C/C++unsigned,size_toruintN_tvariable, or a Gouintvariable, declared above in the same file (including in theforstatement itself) with no later signed redeclaration. - One operand required to differ from one of two different constants:
role != ROLE_ADMIN || role != ROLE_OWNER. - Two ranges on one operand that cover every value:
port > 1024 || port < 65535. - An operand compared with itself:
mine.id == mine.id, or a no-argument getter call on both sides,mine.getOwnerId() == mine.getOwnerId().
for (size_t i = n - 1; i >= 0; i--) { /* never ends: i wraps to SIZE_MAX */
printf("%d\n", v[i]);
}
if (role != ROLE_ADMIN || role != ROLE_OWNER) { // every role passes
return false;
}
What Is Not Flagged
- Constant conditions written on purpose:
if (true),while (1),for (;;). x != xandv == von a float or double declared above: the NaN tests.- Signed variables, cast operands (
(int)cap >= 0) and members of other objects (p->n >= 0). - Comparisons in string literals or comments, and test code.
Remediation
- For a reverse loop over an unsigned index, count down with
for (size_t i = n; i-- > 0;), or use a signed index. - For
x != A || x != B, the intended operator is almost always&&. - For a self-comparison, compare with the other object (
mine.id == other.id).
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-571
// nosec vnx-571
Or record an ignore rule: vulnetix ignore add --rule vnx-571 --reason "...". See Suppressing findings.