Skip to content

VNX-229: Improper Handling of Values

A request value is converted to a number with no handling of a missing or malformed value: Python int()/float() of a request value outside try, or Node.js parseInt/parseFloat/Number of req.query or req.body whose NaN is never handled.

Updated 02 Nov 2026Checked against cli@de9b52a
Field Value
Rule ID VNX-229
Severity Low
SARIF level note
Kind sast
Languages JavaScript / TypeScript, Python
CWE CWE-229
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 improper-handling-of-values cwe-229 input-validation
Source internal/sast/rules/vnx-229.rego

Overview

VNX-229 maps to CWE-229: Improper Handling of Values. It reports a request value converted to a number where a missing or malformed value is not handled:

  • Python: int() or float() applied to a Flask, Django or DRF request value (request.args, form, values, GET, POST, json, get_json(), data, cookies, headers, query_params), inline or through a variable assigned from one in the eight lines above, outside any try block.
  • Node.js / TypeScript: parseInt(), parseFloat() or Number() of req.query or req.body (inline, or through an assigned or destructured variable) whose result is neither defaulted on the same line (||, ??) nor tested with isNaN, Number.isNaN, isFinite or Number.isInteger in the lines that follow.

Why This Matters

In Python a missing parameter raises TypeError and a non-numeric one ValueError, so any client can turn the endpoint into a 500; float() also accepts "nan" and "inf", which then poison arithmetic such as balances and discounts. In JavaScript the conversion never fails: it yields NaN, which flows into queries and calculations.

Not reported: Flask’s get(..., type=int), a conversion inside try or with contextlib.suppress(...), a value guarded by isdigit()/isnumeric()/isdecimal() or a regex match just above, route parameters (req.params, constrained by the route pattern), constants and environment values, commented-out code and string literals.

What Gets Flagged

src.balance -= int(request.form['amount'])

page = request.GET.get("page", 1)
offset = (int(page) - 1) * 20
const limit = parseInt(req.query.limit, 10);
const items = await Item.find().limit(limit);

Remediation

page = request.args.get("page", 1, type=int)
try:
    amount = int(request.form["amount"])
except (TypeError, ValueError):
    abort(400)
const limit = parseInt(req.query.limit, 10);
if (Number.isNaN(limit)) return res.status(400).send("bad limit");

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

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

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