Skip to content

VNX-654: Reliance on a Single Factor in a Security Decision

Reports an if/elif that grants access (next(), login, a session admin flag, return True) because the client address or a Referer/X-Forwarded-For/X-Real-IP header matched, with no authenticated identity in the condition.

Updated 02 Nov 2026Checked against cli@de9b52a
Field Value
Rule ID VNX-654
Severity Low
SARIF level note
Kind sast
Languages JavaScript / TypeScript, Python
CWE CWE-654
CAPEC CAPEC-66
ATT&CK T1190
CWSS vector CWSS:1.0/TI:L/AP:A/AL:A/IC:N/FC:LT/RP:N/RL:A/AV:I/AS:N/IN:A/SC:A/BI:L/DI:H/EX:L/EC:N/P:L
Tags authentication ip-allowlist single-factor cwe-654
Source internal/sast/rules/vnx-654.rego

Overview

VNX-654 maps to CWE-654: Reliance on a Single Factor in a Security Decision. It reports a condition that tests the client’s network origin and a branch that grants access on that alone.

  • Origin read: Python request.remote_addr, request.access_route, request.client.host, REMOTE_ADDR, HTTP_X_FORWARDED_FOR, HTTP_X_REAL_IP, HTTP_REFERER, request.referrer and the X-Forwarded-For/X-Real-IP/X-Client-IP/Referer headers; JavaScript req.ip, req.ips, Koa ctx.ip/ctx.request.ip, .remoteAddress and the same headers. It can be read directly or through a variable assigned a few lines above.
  • Comparison: ==, ===, in, includes, startswith/startsWith, indexOf, a regex test.
  • Grant in the branch: return next()/next()/await next(), login()/login_user(), a session admin/user/authenticated flag, is_admin = True, return True, a decorator returning the wrapped view.

Not reported: a condition that also checks the authenticated user, session, token or password, negated checks and blocklists, logging, rate limiting, region lookups, a grant behind a nested check, test files, comments and string literals.

Why This Matters

X-Forwarded-For and Referer are written by the client. A real address is shared behind NAT and proxies, and “localhost” is exactly where an SSRF request comes from. None of them proves who the caller is.

What Gets Flagged

if request.remote_addr == "127.0.0.1":          # FLAGGED
    return f(*args, **kwargs)
if (OFFICE.includes(req.ip)) {                  // FLAGGED
  return next()
}
# NOT FLAGGED: address plus an authenticated user
if request.remote_addr in ALLOWED and current_user.is_authenticated:
    return f(*args, **kwargs)

Remediation

  1. Authenticate the caller (session, token, mTLS) and use the network check only as an additional restriction.
  2. Never trust X-Forwarded-For unless a known proxy sets it; configure the framework’s trusted-proxy list instead.

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

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

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