VNX-1024: Comparison of incompatible types (always false)
Reports Java equals() between a declared type and a literal of another type (String vs number, Long vs int literal, UUID vs string) and Python string input compared with an int literal, checks that can never pass.
| Field | Value |
|---|---|
| Rule ID | VNX-1024 |
| Severity | Low |
| SARIF level | note |
| Kind | sast |
| Languages | Java, Python |
| CWE | CWE-1024 |
| 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 | comparison-of-incompatible-types always-false cwe-1024 |
| Source | internal/sast/rules/vnx-1024.rego |
Overview
VNX-1024 maps to CWE-1024: Comparison of Incompatible Types. It reports equality checks that can never be true because the two sides have different types:
- Java:
x.equals(y)orObjects.equals(x, y)wherexis declared in the file with exactly one type andyis a literal of another: aStringagainst a number, boolean or char; aLongagainst an int literal (5boxes toInteger, which never equals aLong) or a string; anInteger/Short/Byteagainst a long, decimal or string; aDouble/Floatagainst an int or string; aBoolean,Character,BigDecimal,BigIntegerorUUIDagainst a string; and"literal".equals(number). - Python: a value read as a string (
input(),sys.argv[...],os.environ.get,os.getenv, Flaskrequest.args/form/headers/cookies, Djangorequest.GET/POST) compared with==/!=to an int or float literal, directly or through a variable assigned from it a few lines above and not converted since.
Not reported: names declared with more than one type in the file, request.args.get(..., type=int), a .get() or os.getenv() with a numeric default, values converted with int()/float()/len(), ordering comparisons, comments and string literals.
Why This Matters
A check that is constantly false silently disables what it guards (an admin gate that never opens is harmless; a “deny if role == 0” that never fires is not), and a negated one is constantly true.
What Gets Flagged
private Long ownerId;
return ownerId.equals(0); // Integer 0 never equals a Long
if (level.equals(1)) { ... } // level is a String
role = request.args.get("role")
if role == 1: # a str never equals an int
return grant()
Remediation
- Compare values of the same type: parse the string first (
Integer.parseInt,int()), or compare with a literal of the right type (0L,"1"). - In Flask, read typed parameters with
request.args.get(name, type=int).
References
- CWE-1024
- SEI CERT EXP03-J: Do not use the equality operators when comparing values of boxed primitives
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-1024
// nosec vnx-1024
Or record an ignore rule: vulnetix ignore add --rule vnx-1024 --reason "...". See Suppressing findings.