Skip to content

VNX-179: Incorrect Behavior Order: Early Validation

Reports a check for a dangerous sequence (.., /, <script, a quote) that runs before the same value is URL-, HTML- or Unicode-decoded, and a check on the raw query string before a decoded parameter is read.

Updated 02 Nov 2026Checked against cli@de9b52a
Field Value
Rule ID VNX-179
Severity Medium
SARIF level warning
Kind sast
Languages Java, Python, JavaScript / TypeScript, Go, PHP
CWE CWE-179
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 validation ordering canonicalization cwe-179
Source internal/sast/rules/vnx-179.rego

Overview

VNX-179 maps to CWE-179: Incorrect Behavior Order: Early Validation. It reports a condition that checks a value for a dangerous sequence (.., ../, /, \, <, <script, a quote) when the same value is decoded or canonicalised within the next ten lines:

  • Java URLDecoder.decode, Normalizer.normalize
  • Python unquote/unquote_plus, html.unescape, unicodedata.normalize
  • JavaScript decodeURI/decodeURIComponent
  • Go url.PathUnescape/url.QueryUnescape
  • PHP urldecode/rawurldecode/html_entity_decode

It also reports a check on the raw query string, request URI or URL (Java getQueryString()/getRequestURI(), Python request.query_string/request.full_path, Express req.originalUrl/req.url, Go r.URL.RawQuery/RawPath, PHP $_SERVER['QUERY_STRING']/['REQUEST_URI']), directly or through a variable assigned from it, followed within ten lines by a decoded parameter read (getParameter, request.args, req.query/req.params, URL.Query().Get, FormValue, $_GET/$_REQUEST), because the framework decodes the parameter after the check has passed.

The supported checks are contains/includes/indexOf/startsWith/matches, Python in, strings.Contains/HasPrefix/Index, strpos/stripos/str_contains/strstr, and a regular expression for .. or <script (/\.\.\//.test(x), re.search(r"\.\.", x)). Not reported: decoding before the check, a check on a different variable, a decoded value that is checked again within six lines, a check that also rejects % (encoded input), comments and string literals.

Why This Matters

A check made before decoding inspects a form of the data that is not the one used. %2e%2e%2f contains no ../, passes the check, and becomes ../ one line later.

What Gets Flagged

// FLAGGED: checked, then decoded
if (file == null || file.contains("..")) { ... }
String name = URLDecoder.decode(file, StandardCharsets.UTF_8);

// FLAGGED: raw query string checked, decoded parameter used
var query = request.getQueryString();
if (query != null && (query.contains("..") || query.contains("/"))) { ... }
var id = request.getParameter("id");
// FLAGGED
if (p.includes('../')) return res.status(400).end();
const target = decodeURIComponent(p);
// FLAGGED: raw query checked, decoded parameter used
if strings.Contains(r.URL.RawQuery, "..") { ... }
name := r.URL.Query().Get("name")
# NOT FLAGGED: decoded first, then checked
name = unquote(request.args.get("name", ""))
if ".." in name:
    abort(400)

Remediation

  1. Decode and canonicalise input completely before validating it.
  2. Validate the exact value that is used, not an earlier form of it.
  3. For paths, resolve the final path and check that it stays under its base directory.

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

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

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