Skip to content

VNX-603: Authentication decided in browser code

Reports browser JavaScript that decides authentication itself: a literal login or role flag written to localStorage, sessionStorage or document.cookie, such a flag read back to gate the page, or a password or PIN compared with a string literal.

Updated 02 Nov 2026Checked against cli@de9b52a
Field Value
Rule ID VNX-603
Severity Medium
SARIF level warning
Kind sast
Languages JavaScript / TypeScript
CWE CWE-603
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 javascript browser authentication client-side-auth cwe-603
Source internal/sast/rules/vnx-603.rego

Overview

VNX-603 maps to CWE-603: Use of Client-Side Authentication. Anything the browser decides, the user can change from the developer console.

The rule reports:

  • a login or role flag written as a literal to localStorage/sessionStorage (setItem('isLoggedIn', 'true'), sessionStorage.isAdmin = true) or to document.cookie (loggedIn=true, role=admin);
  • such a flag read back from storage and compared or tested to gate the page, directly or through a variable it was read into and a condition tests within the next 10 lines;
  • a password, passcode or PIN (a variable so named, or the .value of an element whose id names one) compared with a non-empty string literal, in a file that uses the DOM and is not server code.

Flag names are isLoggedIn/loggedIn/logged_in, isAuthenticated/authenticated/auth, isAdmin/admin, role/userRole, and isAuthorized/authorized.

It does not report tokens stored or sent to the server (the server verifies them), flags set from a server response rather than a literal, clearing a flag (removeItem, 'false'), unrelated preferences (theme, consent), empty-string checks, server-side password comparison (bcrypt.compare, req.body), or comments and prose inside string literals.

What Gets Flagged

localStorage.setItem('isLoggedIn', 'true');                 // FLAGGED
if (localStorage.getItem('isLoggedIn') !== 'true') { }      // FLAGGED
if (user === 'admin' && pass === 'S3cretPass!') { }         // FLAGGED
document.cookie = "loggedIn=true; path=/";                  // FLAGGED

// NOT FLAGGED
localStorage.setItem('token', res.accessToken);
fetch('/api/me', { headers: { Authorization: 'Bearer ' + token } });
localStorage.setItem('theme', 'dark');

Remediation

  1. Authenticate on the server and keep the result in a server-side session or a signed token.
  2. Gate every protected page and API on the server; browser-side checks are for display only.
  3. Never ship a password or PIN to the browser to compare against.

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

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

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