Skip to content

VNX-184: Incomplete List of Disallowed Inputs

Reports input validation by deny-list: a collection of attack tokens (shell metacharacters, <script/javascript:, ../, SQL comment and keyword tokens, executable extensions) that is named as a deny-list or applied to input with contains/replace/in.

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

Overview

VNX-184 maps to CWE-184: Incomplete List of Disallowed Inputs. It reports a collection literal (Python list/tuple/set/dict, JavaScript array, Java List.of/Arrays.asList/Set.of, Go slice or map, PHP array(...)) whose entries are attack tokens, when either:

  • the variable is named as a deny-list (blacklist, denylist, blocklist, forbidden…, disallowed…, banned…, blocked…, dangerous…, unsafe…, bad…, …filter) and holds at least one such token; or
  • it holds two or more tokens of one family and the file applies it within 40 lines (contains, includes, replace, str_replace(array_keys(...)), in, a for/range loop).

The families are shell metacharacters (; && | || & ` $( > <), script and HTML (&lt;script, javascript:, onerror, onload, &lt;iframe), traversal (../, ..\, /etc/passwd) and SQL (--, /*, ', union, select, drop…, with at least one comment, quote or union token). Executable extensions (.php, .exe, .jsp, .sh…) count for a deny-named list.

Not reported: escaping tables (entries mapped to a non-empty replacement), allow-lists, deny-named lists of other values (IP addresses, user names), token lists the file never applies, test files, comments and string literals.

Why This Matters

A deny-list is a guess at every dangerous input. Removing ; and && leaves |, ||, a newline and $(...); rejecting <script leaves <img onerror=...>; rejecting .php leaves .phtml and .PHP. The attacker only needs the one the list forgot.

What Gets Flagged

// FLAGGED: removing two shell separators before shell_exec
$substitutions = array(
    '&&' => '',
    ';'  => '',
);
$target = str_replace(array_keys($substitutions), $substitutions, $target);
// FLAGGED
private static final List<String> DENY_LIST = List.of(";", "&&", "|");
// FLAGGED
var forbiddenExtensions = []string{".php", ".exe", ".sh"}
# NOT FLAGGED: an escaping table and an IP block-list
HTML_ESCAPES = {"&": "&amp;", "<": "&lt;", ">": "&gt;"}
BLOCKED_IPS = ["10.0.0.1"]

Remediation

  1. Validate against an allow-list of what is permitted (a host-name pattern, a set of extensions, an enum of values).
  2. Better still, use the API that removes the need to filter: an argument array instead of a shell string, a parameterised query, context-aware output encoding.

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

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

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