Skip to content

VNX-237: Improper Handling of Structural Elements

A form or query-string parser is configured or called without a limit on field count, nesting depth or array length: unbounded parameterLimit/arrayLimit/depth/maxKeys in Node.js, None for Django/Werkzeug field limits, or parse_qs of a raw request body without max_num_fields.

Updated 02 Nov 2026Checked against cli@de9b52a
Field Value
Rule ID VNX-237
Severity Low
SARIF level note
Kind sast
Languages JavaScript / TypeScript, Python
CWE CWE-237
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 structural-elements cwe-237 resource-limits denial-of-service
Source internal/sast/rules/vnx-237.rego

Overview

VNX-237 maps to CWE-237: Improper Handling of Structural Elements. It reports a parser of untrusted form or query data whose limit on structural elements has been removed:

  • Node.js / TypeScript: an option of express.urlencoded(), bodyParser.urlencoded(), qs.parse() or querystring.parse() set to Infinity (or Number.MAX_SAFE_INTEGER, MAX_VALUE, POSITIVE_INFINITY) or far past the library default: parameterLimit of 100000 or more, arrayLimit of 10000 or more, depth of 50 or more, and querystring’s maxKeys: 0, which means unlimited.
  • Python: Django’s DATA_UPLOAD_MAX_NUMBER_FIELDS or DATA_UPLOAD_MAX_NUMBER_FILES, Werkzeug’s max_form_parts or Flask’s MAX_FORM_PARTS set to None; and urllib.parse.parse_qs()/parse_qsl() of a raw request body (self.rfile.read(), request.body, request.get_data(), environ['wsgi.input'].read()) without max_num_fields.

Why This Matters

The limits exist because parsing cost grows with the number and nesting of elements, not only with body size. Without them a single small request such as a[][][]...=1 or a million &x=1 pairs makes the server allocate a huge object and spend seconds of CPU on it.

Not reported: limits at or near the defaults, a depth option of an unrelated API (util.inspect, a tree walker), parse_qs of a URL’s query string, comments, string values and test code.

What Gets Flagged

app.use(express.urlencoded({ extended: true, parameterLimit: 10000000 }));
app.set("query parser", (str) => qs.parse(str, { depth: Infinity }));
DATA_UPLOAD_MAX_NUMBER_FIELDS = None

body = environ["wsgi.input"].read(size).decode()
form = parse_qs(body)

Remediation

Keep the defaults, or set a bound sized to the largest legitimate form:

app.use(express.urlencoded({ extended: true, parameterLimit: 2000 }));
form = parse_qs(body, max_num_fields=200)

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

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

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