Skip to content

VNX-627: Dynamic Variable Evaluation

Detects a program variable whose name comes from the request: Python globals()/locals()/vars() indexed or updated with request data, Ruby instance_variable_set/get with params in the name, PHP variable variables named by a superglobal, and JavaScript global[...] or window[...] indexed by req input.

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

Overview

VNX-627 maps to CWE-627: Dynamic Variable Evaluation. When the client chooses the name of the variable a program reads or writes, it can overwrite $is_admin, a configuration global or the instance variable that holds the current user, or read a secret the page was never meant to show.

Reported:

  • Python: globals()[k], locals()[k], vars()[k] (or globals().get(k)) where k is a request value (request.args, form, values, json, GET, POST, data, cookies, headers, query_params), and globals().update(...), vars(x).update(...), x.__dict__.update(...) with request data.
  • Ruby: instance_variable_set/get, class_variable_set/get and binding.local_variable_set/get whose name interpolates params, cookies or request parameters.
  • PHP: $$name, ${$name} and ${$_GET[...]} where the name is a superglobal or a variable assigned from one.
  • JavaScript/TypeScript: global[...], globalThis[...], window[...] indexed by req.query, body, params, cookies or headers.

The request value may be inline or reach the sink through a variable assigned from it, a destructuring, a for loop or an each block in the 10 lines above.

What Gets Flagged

for key, value in request.POST.items():
    globals()[key] = value          # FLAGGED
instance_variable_set("@#{params[:field]}", params[:value])   # FLAGGED
$name = $_GET['var'];
$$name = $_GET['value'];            // FLAGGED
res.send(String(global[req.query.name]));   // FLAGGED

What Is Not Flagged

  • Constant names (globals()["LAST_LOOKUP"] = name, instance_variable_set(:@theme, ...)).
  • Names from function parameters or configuration: there is no cross-function dataflow.
  • Ordinary dictionary or object lookups (HANDLERS.get(name), handlers[req.query.name]).
  • PHP variable variables inside a foreach over a superglobal and extract(): VNX-PHP-007 reports those.
  • The sinks inside comments or string literals.

Remediation

Never let input name a variable. Map the allowed names to values explicitly:

ALLOWED = {"theme", "locale"}
settings = {k: v for k, v in request.form.items() if k in ALLOWED}

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

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

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