Skip to content

VNX-839: Numeric Range Comparison Without Minimum Check

Detects a signed integer from untrusted input that is checked only against a maximum and then used as an array or list index, so a negative value passes. Python, Java, C and C++.

Updated 02 Nov 2026Checked against cli@de9b52a
Field Value
Rule ID VNX-839
Severity Medium
SARIF level warning
Kind sast
Languages Python, Java, C, C++
CWE CWE-839
CAPEC CAPEC-66
ATT&CK T1190
CWSS vector CWSS:1.0/TI:M/AP:RU/AL:S/IC:N/FC:LT/RP:RU/RL:S/AV:L/AS:N/IN:A/SC:A/BI:M/DI:H/EX:M/EC:N/P:C
Tags numeric-range bounds-check negative-index cwe-839
Source internal/sast/rules/vnx-839.rego

Overview

VNX-839 maps to CWE-839: Numeric Range Comparison Without Minimum Check. if (idx < size) is only half a bounds check when idx is signed. A negative number satisfies it, and then indexes from the end of a Python list, throws in Java, or reads and writes before the start of a C array.

The rule follows a value read from untrusted input (Python int() of request.*, sys.argv or input(); Java Integer.parseInt/valueOf or Long.parseLong of getParameter()/getHeader() or of a variable assigned from one just above, Scanner.nextInt(); C/C++ atoi/atol/strtol, std::stoi/stol, or sscanf with %d into a signed variable). It reports the comparison when the value is checked against an upper bound within six lines, then used as an index (or, in Java, passed to List.get) within eight lines of the check, with no lower-bound check in between.

What Gets Flagged

idx = int(request.args.get("i", "0"))
if idx < len(ITEMS):          # FLAGGED: idx = -1 returns the last item
    return ITEMS[idx]
int idx = atoi(arg);
if (idx >= 16)                /* FLAGGED: idx = -5 writes before names[] */
    return -1;
names[idx] = value;

What Is Not Flagged

  • Range checks that also test the minimum: 0 <= i < n, i < 0 || i >= n, i >= 0 && i < n.
  • Values clamped with max(0, ...), Math.max(0, ...) or abs(), or validated with isdigit().
  • unsigned/size_t variables and strtoul, constants, and values compared but never used as an index.

Remediation

Check both ends of the range, or parse into an unsigned type:

if not 0 <= idx < len(ITEMS):
    abort(404)

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

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

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