Skip to content

VNX-1094: Excessive Index Range Scan for a Data Resource

Python DB-API code that runs a SELECT over a caller-chosen range (BETWEEN or </>= against placeholders) with no LIMIT or aggregate and then loads every row with fetchall().

Updated 02 Nov 2026Checked against cli@de9b52a
Field Value
Rule ID VNX-1094
Severity Low
SARIF level note
Kind sast
Languages Python
CWE CWE-1094
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 sql performance resource-consumption cwe-1094
Source internal/sast/rules/vnx-1094.rego

Overview

VNX-1094 maps to CWE-1094: Excessive Index Range Scan for a Data Resource. It reports a cursor.execute(...) call whose SQL (inline, triple-quoted, or assigned to a variable a few lines above) is a SELECT with an open range predicate over placeholders (BETWEEN %s AND %s, amount >= ?, ts > :since, %(name)s, $1), with no LIMIT, TOP, FETCH FIRST or aggregate, when fetchall() follows within a few lines.

Why This Matters

The width of the range decides how many index entries are scanned and how many rows are pulled into memory, and here the caller decides it. One request with a wide range becomes a scan of the table and a large in-memory list, which is a cheap way to exhaust a database or a worker.

Not reported: queries with LIMIT/TOP/FETCH FIRST, aggregates (COUNT, SUM, MIN, MAX, AVG), equality predicates, results read with fetchone() or fetchmany(), ORM queries, test files and comments.

What Gets Flagged

cur.execute("SELECT * FROM orders WHERE created_at BETWEEN %s AND %s", (start, end))   # FLAGGED
return cur.fetchall()

sql = "SELECT id, kind FROM events WHERE ts >= %(since)s ORDER BY ts"
cursor.execute(sql, {"since": since})                                                  # FLAGGED
for row in cursor.fetchall():
    ...

Remediation

  1. Cap the range on the server side (a maximum span between the bounds) before running the query.
  2. Add LIMIT/OFFSET or keyset pagination, or stream with fetchmany(n).
  3. For a confirmed false positive, add a # vulnetix-ignore: VNX-1094 comment on the line.

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

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

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