Skip to content

VNX-450: Multiple interpretations of input: a text flag read as a boolean by truthiness

Detects a configuration or request flag that arrives as text and is made boolean by truthiness, so 'false', '0' and 'no' all mean on: Python bool() of os.environ/getenv, request parameters, sys.argv or input(), os.environ.get with a True/False default, argparse type=bool, and Node Boolean()/!! of process.env/req.query or process.env.X || true/false.

Updated 02 Nov 2026Checked against cli@de9b52a
Field Value
Rule ID VNX-450
Severity Low
SARIF level note
Kind sast
Languages Python, JavaScript / TypeScript
CWE CWE-450
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 multiple-interpretations truthiness configuration cwe-450
Source internal/sast/rules/vnx-450.rego

Overview

VNX-450 maps to CWE-450: Multiple Interpretations of UI Input. An operator who sets APP_DEBUG=false, or a user who answers “no”, means off. Code that turns that text into a boolean by truthiness reads every non-empty string as on, silently choosing the less safe interpretation.

The rule reports:

  1. Python bool() around os.environ/os.getenv, a Flask or Django request parameter (directly or through a variable assigned from one in the six lines above), or sys.argv, when the line names a switch (debug, enable, allow, skip, require, verify, secure, tls, csrf, auth, admin, public, include, notify, verbose, feature, flag…); and bool(input(...)) always.
  2. Python os.environ.get(name, True|False) / os.getenv(name, True|False) that is not parsed: once set, the value is a non-empty string.
  3. Node Boolean(process.env.X) / Boolean(req.query.x) naming a switch, and process.env.X || true|false or ?? true|false.

Not reported: values parsed explicitly (strtobool, ==/!=, in (...), .lower(), int()), string defaults, bool() of a token, URL, path or DSN (a deliberate is-it-set test), bool() of ordinary values, comments, strings, docstrings and test files.

What Gets Flagged

# FLAGGED: WEB_DEBUG=false still enables debug
WEB_DEBUG = os.environ.get("WEB_DEBUG", True)
DEBUG = bool(os.environ.get("APP_DEBUG"))
parser.add_argument("--dry-run", default=False, type=bool)

# NOT FLAGGED: parsed explicitly
DEBUG = os.environ.get("APP_DEBUG", "false").lower() in ("1", "true", "yes")
// FLAGGED: STRICT_TLS=false is truthy
const strictTls = process.env.STRICT_TLS || true;
const allowSignup = !!process.env.ALLOW_SIGNUP;

Remediation

Parse flags explicitly against an accepted set (value.strip().lower() in {"1", "true", "yes", "on"}, process.env.X === 'true'), and use typed config loaders (getboolean, pydantic, envalid) where available.

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

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

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