VNX-1004: Sensitive cookie set without the HttpOnly flag
Reports session, authentication and identity cookies set without HttpOnly in Go, Node.js, PHP, Python and Java, and framework settings that turn the session cookie's HttpOnly flag off.
| Field | Value |
|---|---|
| Rule ID | VNX-1004 |
| Severity | Medium |
| SARIF level | warning |
| Kind | sast |
| Languages | Go, JavaScript / TypeScript, PHP, Python, Java |
| CWE | CWE-1004 |
| 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 | cookie httponly session cwe-1004 |
| Source | internal/sast/rules/vnx-1004.rego |
Overview
VNX-1004 maps to CWE-1004: Sensitive Cookie Without ‘HttpOnly’ Flag. It reports a cookie whose name says it carries a session, authentication or identity value (session, sid, auth, token, jwt, access/refresh, remember, login, userid, admin, role, …; a constant naming the cookie is resolved within the file) when it is set without HttpOnly:
- Go:
http.Cookie{...}literals withoutHttpOnly: true(and no later.HttpOnly = true);HttpOnly: falsein a session store’sOptions. - Node.js: Express
res.cookie(...)and Fastifyreply.setCookie(...)of an identity or role cookie (user_id,uid,admin,role) withouthttpOnly: true;httpOnly: falsein express-session or cookie-session options; a session token written todocument.cookie. A session or credential cookie set byres.cookie()/reply.setCookie()without httpOnly, andhttpOnly: falsebeside a cookie call, are reported by VNX-NODE-029, the Node.js form of this rule, and not again here. - PHP:
setcookie()/setrawcookie()without the httponly argument or with it false;ini_set('session.cookie_httponly', 0);session_set_cookie_paramswith httponly false. - Python:
set_cookie(...)(Flask, Django, Starlette) withouthttponly=True;SESSION_COOKIE_HTTPONLY = False. - Java:
new Cookie(...)with nosetHttpOnly(true)on it in the following lines;ResponseCookie.from(...)builders without.httpOnly(true);server.servlet.session.cookie.http-only=false.
Not reported: cookies with other names (preferences and lookalikes such as author_view or accessibility_mode, CSRF/XSRF tokens, which double-submit schemes must let scripts read), cookies being deleted, wrappers that take HttpOnly as a parameter, Koa ctx.cookies.set (HttpOnly by default), test files and comments.
Why This Matters
A cookie without HttpOnly is readable through document.cookie, so a single cross-site scripting flaw anywhere on the origin hands the attacker the victim’s session. Express, Flask, Django, Starlette and PHP’s setcookie all default to readable cookies.
What Gets Flagged
res.cookie('user_id', user.id); // FLAGGED
res.cookie('token', token); // reported by VNX-NODE-029, not VNX-1004
resp.set_cookie("session_id", token)
SESSION_COOKIE_HTTPONLY = False
setcookie('session_token', $token);
ini_set('session.cookie_httponly', 0);
http.SetCookie(w, &http.Cookie{Name: "auth_token", Value: token, Path: "/"})
Cookie cookie = new Cookie("access_token", token);
response.addCookie(cookie);
Remediation
- Set HttpOnly on every cookie that carries a session or credential:
{ httpOnly: true },httponly=True,HttpOnly: true,cookie.setHttpOnly(true), or the seventhsetcookieargument /'httponly' => true. - Remove overrides that turn the framework session cookie’s HttpOnly off.
- Set Secure and SameSite on the same cookies.
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-1004
// nosec vnx-1004
Or record an ignore rule: vulnetix ignore add --rule vnx-1004 --reason "...". See Suppressing findings.