javascript.express.security.audit.express-cookie-settings.express-cookie-session-no-domain

Author
3,077
Download Count*
License
Default session middleware settings: domain
not set. It indicates the domain of the cookie; use it to compare against the domain of the server in which the URL is being requested. If they match, then check the path attribute next.
Run Locally
Run in CI
Defintion
rules:
- id: express-cookie-session-no-domain
message: "Default session middleware settings: `domain` not set. It indicates
the domain of the cookie; use it to compare against the domain of the
server in which the URL is being requested. If they match, then check the
path attribute next."
severity: WARNING
languages:
- javascript
- typescript
metadata:
cwe:
- "CWE-522: Insufficiently Protected Credentials"
owasp:
- A02:2017 - Broken Authentication
- A04:2021 - Insecure Design
source-rule-url: https://expressjs.com/en/advanced/best-practice-security.html
category: security
technology:
- express
cwe2021-top25: true
subcategory:
- vuln
likelihood: HIGH
impact: LOW
confidence: MEDIUM
references:
- https://owasp.org/Top10/A04_2021-Insecure_Design
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
patterns:
- pattern-either:
- pattern-inside: |
$SESSION = require('cookie-session');
...
- pattern-inside: |
$SESSION = require('express-session');
...
- pattern: $SESSION(...)
- pattern-not-inside: $SESSION(<... {cookie:{domain:...}} ...>,...)
- pattern-not-inside: |
$OPTS = <... {cookie:{domain:...}} ...>;
...
$SESSION($OPTS,...);
- pattern-not-inside: |
$OPTS = ...;
...
$COOKIE = <... {domain:...} ...>;
...
$SESSION($OPTS,...);
- pattern-not-inside: |
$OPTS = ...;
...
$OPTS.cookie = <... {domain:...} ...>;
...
$SESSION($OPTS,...);
- pattern-not-inside: |
$OPTS = ...;
...
$COOKIE.domain = ...;
...
$SESSION($OPTS,...);
- pattern-not-inside: |
$OPTS = ...;
...
$OPTS.cookie.domain = ...;
...
$SESSION($OPTS,...);
Examples
express-cookie-settings.js
var session = require('express-session')
var express = require('express')
var app = express()
function test1() {
var expiryDate = new Date(Date.now() + 60 * 60 * 1000) // 1 hour
var opts = {
keys: ['key1', 'key2'],
cookie: {
secure: true,
httpOnly: true,
domain: 'example.com',
path: 'foo/bar',
expires: expiryDate
}
}
// ruleid: express-cookie-session-default-name
app.use(session(opts))
}
function test2() {
// ruleid: express-cookie-session-no-secure
app.use(session(Object.assign({
keys: ['key1', 'key2'],
name: 'foo'
}, {
cookie: {
httpOnly: true,
domain: 'example.com',
path: 'foo/bar',
expires: new Date(Date.now() + 60 * 60 * 1000)
}
})))
}
function test3() {
// ruleid: express-cookie-session-no-httponly
app.use(session({
keys: ['key1', 'key2'],
name: 'foo',
cookie: {
secure: true,
domain: 'example.com',
path: 'foo/bar',
expires: new Date(Date.now() + 60 * 60 * 1000)
}
}))
}
function test4() {
var opts = {
keys: ['key1', 'key2'],
name: 'foo',
}
if (app.get('env') === 'production') {
app.set('trust proxy', 1) // trust first proxy
opts.cookie = {
secure: true,
httpOnly: true,
path: 'foo/bar',
expires: new Date(Date.now() + 60 * 60 * 1000)
}
}
// ruleid: express-cookie-session-no-domain
app.use(session(opts))
}
function test5() {
var expiryDate = new Date(Date.now() + 60 * 60 * 1000) // 1 hour
var opts = {
keys: ['key1', 'key2'],
name: 'foo',
cookie: {
secure: true,
httpOnly: true
}
}
if (app.get('env') === 'production') {
app.set('trust proxy', 1) // trust first proxy
opts.cookie.domain = 'example.com'
opts.cookie.expires = expiryDate
}
// ruleid: express-cookie-session-no-path
app.use(session(opts))
}
function test6() {
var opts = {
keys: ['key1', 'key2'],
name: 'foo',
cookie: {
secure: true,
httpOnly: true,
domain: 'example.com',
path: 'foo/bar'
}
}
// ruleid: express-cookie-session-no-expires
app.use(session(opts))
}
function okTest() {
var expiryDate = new Date(Date.now() + 60 * 60 * 1000) // 1 hour
var opts = {
keys: ['key1', 'key2'],
name: 'foo',
cookie: {
secure: true,
httpOnly: true,
domain: 'example.com',
path: 'foo/bar',
expires: expiryDate
}
}
app.use(session(opts))
}
Short Link: https://sg.run/rd41