Skip to content

VNX-115: Misinterpretation of Input

A request value is converted or compared in a way that reads it as something other than what the requester sent, so the program acts on a different value than the one it checked or meant (CWE-115). Reported: JavaScript/TypeScript parseInt/Number.parseInt of request data with no radix argument ("0x10" is read as 16); JavaScript Boolean(x) or !!x and Python bool(x) of a string request value (req.query/params/headers/cookies; request.args/form/values/GET/POST/cookies/headers .get() or [...]), which is true for "false" and "0"; PHP loose comparison (== or !=) of request data with a token, password, hash, secret, signature, key, code or PIN ("0e..." magic hashes and type juggling make unequal values equal), strcmp() of request data tested with == 0 or ! (an array argument returns NULL, which equals 0), and in_array() of request data without the strict third argument. Request data is used inline or through a variable assigned from it in the 25 lines above. Not reported: parseInt with a radix, Number(), explicit comparisons such as === 'true' or .lower() == 'true', bool() of a whole collection (bool(request.args)), JSON body values in the Boolean checks (already typed), ===, hash_equals and password_verify, in_array(..., true), loose comparison with an ordinary string, and code in comments. Two shapes are reported by a more precise rule, so the line is reported once: a radix-less parseInt of request data used inline or through a variable assigned within the 10 lines above by VNX-1389 (incorrect parsing of numbers with different radices), and a PHP loose comparison or strcmp() test that VNX-PHP-010 reports (PHP type juggling); this rule keeps the longer 25-line flows, the Boolean/bool checks and non-strict in_array().

Updated 02 Nov 2026Checked against cli@de9b52a
Field Value
Rule ID VNX-115
Severity Medium
SARIF level warning
Kind sast
Languages JavaScript / TypeScript, PHP, Python
CWE CWE-115
CAPEC CAPEC-66
ATT&CK T1190
CWSS vector CWSS:1.0/TI:M/AP:RU/AL:S/IC:N/FC:LT/RP:RU/RL:S/AV:L/AS:N/IN:A/SC:A/BI:M/DI:H/EX:M/EC:N/P:C
Tags misinterpretation type-juggling input cwe-115
Source internal/sast/rules/vnx-115.rego

Overview

VNX-115 maps to CWE-115: Misinterpretation of Input. It reports conversions and comparisons that interpret a request value differently from what the requester sent, when the value is used inline or through a variable assigned from the request in the 25 lines above:

  • JavaScript/TypeScript parseInt() / Number.parseInt() of request data with no radix ("0x10" becomes 16).
  • JavaScript Boolean(x) / !!x and Python bool(x) of a string request value (query, params, headers, cookies, form): "false" and "0" are true.
  • PHP ==/!= between request data and a token, password, hash, secret, signature, key, code or PIN (type juggling, 0e... magic hashes); strcmp() of request data tested with == 0 or ! (an array argument returns NULL); in_array() of request data without the strict third argument.

Not reported: parseInt(v, 10), Number(), explicit comparisons (=== 'true', .lower() == "true"), bool(request.args), JSON body values in the boolean checks, ===, hash_equals, password_verify, in_array(..., true), and loose comparison with an ordinary string.

Two shapes are reported by a more precise rule, so the same line is not reported twice: a radix-less parseInt of request data used inline or through a variable assigned within the 10 lines above by VNX-1389, and a PHP loose comparison or strcmp() test of request data by VNX-PHP-010. This rule keeps the longer flows (a variable assigned up to 25 lines above), the Boolean/bool checks and non-strict in_array().

Why This Matters

When the program’s reading of a value differs from the requester’s, checks stop meaning what they say. ?include_deleted=false turns the flag on; a reset token of 0e1234 loosely equals another magic-hash token; password[]=x makes strcmp() return NULL and the login succeed.

What Gets Flagged

const isAdmin = Boolean(req.query.admin);       // FLAGGED: "false" is true
// REPORTED BY VNX-1389: const limit = parseInt(req.query.limit);
include_deleted = bool(request.args.get("include_deleted"))   # FLAGGED
<?php
// REPORTED BY VNX-PHP-010: if ($_GET['token'] == $stored) { }
$role = $_GET['role'];
if (in_array($role, ['viewer', 'editor'])) { }                 // FLAGGED

Not flagged: parseInt(req.query.limit, 10), req.query.admin === 'true', request.args.get("x", type=str2bool), hash_equals($stored, $_GET['token']), in_array($_GET['role'], [...], true), $_GET['page'] == 'home'.

Remediation

  1. Always pass a radix to parseInt, or use Number() and check Number.isInteger.
  2. Convert boolean flags explicitly: v === 'true', v.lower() in ('1', 'true', 'yes'), or a typed request parser.
  3. In PHP, compare secrets with hash_equals(), passwords with password_verify(), and use === and in_array(..., true) for everything else.

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

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

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