Skip to content

VNX-315: Cleartext Storage of Sensitive Information in a Cookie

A password, card number, CVV, SSN, PIN, bank account number or key written into a cookie in cleartext, by name or by value, across Python, Node, Java, PHP, Ruby and Go cookie APIs.

Updated 02 Nov 2026Checked against cli@de9b52a
Field Value
Rule ID VNX-315
Severity Medium
SARIF level warning
Kind sast
Languages Go, Java, JavaScript / TypeScript, PHP, Python, Ruby
CWE CWE-315
CAPEC CAPEC-97
ATT&CK T1557
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 sensitive-cookie cleartext-storage cwe-315
Source internal/sast/rules/vnx-315.rego

Overview

VNX-315 maps to CWE-315: Cleartext Storage of Sensitive Information in a Cookie. It reports a cookie whose name is a sensitive value (password, card number, CVV, SSN, PIN, bank account or routing number, IBAN, API, private or secret key), or whose value expression names a password, card number, CVV or SSN, set through:

  • Flask/Django set_cookie and set_signed_cookie (signed cookies are readable);
  • Express res.cookie, Koa ctx.cookies.set, Fastify reply.setCookie, js-cookie Cookies.set, document.cookie = "password=...";
  • Java new Cookie(...) and Spring ResponseCookie.from(...);
  • PHP setcookie and setrawcookie;
  • Rails cookies[...], cookies.permanent and cookies.signed;
  • Go http.Cookie{Name: ..., Value: ...}, on one line or several.

Not reported: values passed through a hash, encryption, HMAC or masking call; Rails cookies.encrypted; cookies being cleared (empty value or None); session ids, auth tokens, CSRF tokens and other identifiers; test files and comments.

Why This Matters

A cookie lives in the browser profile, is readable by any script on the page unless it is HttpOnly, is sent with every request, and ends up in proxy and server logs. A password or card number stored there is exposed to anyone with access to the device, the logs or an XSS.

What Gets Flagged

# FLAGGED
resp.set_cookie("password", request.form["password"], max_age=86400)
// FLAGGED
res.cookie('creds', JSON.stringify({ username, password }));
document.cookie = "password=" + pwd + "; path=/";
# FLAGGED
cookies[:password] = params[:password]

Not flagged: res.cookie('session_token', token), cookies.encrypted[:password] = params[:password], setcookie('password', '', time() - 3600).

Remediation

  1. Keep sensitive values on the server, keyed by an opaque session identifier.
  2. If something must travel in a cookie, encrypt it with an authenticated cipher (Rails cookies.encrypted, a server-side key) and mark the cookie Secure, HttpOnly and SameSite.
  3. Never put passwords in a “remember me” cookie: issue a random, revocable remember token 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-315
// nosec vnx-315

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

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