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.
| 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()orquerystring.parse()set toInfinity(orNumber.MAX_SAFE_INTEGER,MAX_VALUE,POSITIVE_INFINITY) or far past the library default:parameterLimitof 100000 or more,arrayLimitof 10000 or more,depthof 50 or more, and querystring’smaxKeys: 0, which means unlimited. - Python: Django’s
DATA_UPLOAD_MAX_NUMBER_FIELDSorDATA_UPLOAD_MAX_NUMBER_FILES, Werkzeug’smax_form_partsor Flask’sMAX_FORM_PARTSset toNone; andurllib.parse.parse_qs()/parse_qsl()of a raw request body (self.rfile.read(),request.body,request.get_data(),environ['wsgi.input'].read()) withoutmax_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
- CWE-237: Improper Handling of Structural Elements
- CWE-770: Allocation of Resources Without Limits or Throttling
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.