sessions.js

ABOUT

This module is concerned with the set up, tear down and protection of sessions. Obligations:

  1. Prevention of session hijacking
    • Generation of session ids, cookies
    • Creation, verification of session ids tied to a session store
    • Regenerating session ids (reauthentication) on priviledged access areas
    • Destruction of session ids after a set period of time (ttl, idle time expiration, cookie expiration), manual logout or moving to/from a privileged access area
  2. Providing a means to generate new cookies which are secure (httpOnly, secure, same-site)
  3. Prevention of cross-site-reguest forgery

REQUIREMENTS & ASSUMPTIONS

require('../security.json').sessionPolicy
const secrets = require('./secrets')
const session = require('express-session')
const csrf = require('csurf')
let redis = require('redis').createClient()
let RedisStore = require('connect-redis')(session)

Neither cookie-parser or body-parser are part of this module–it is assumed that this parsing action will take place within your app.js file (or equivalent)

Many authentication frameworks also include means to attach session state to an authenticated user. _spartan has been tuned to utilize the express-session module as a means to provide this functionality and uses redis (‘connect-redis’) as the means for storing session data. Though commented out, _spartan also supports MongoDB as a session store–you’ll just need to require(connect-mongo) and configure your session object as follows:

let obj = {
  secret: secrets.fetchSecret('SESSION_SECRET'),
  // rolling: true,
  // resave: true,
  saveUninitialized: false,
  cookie: {
    path: secJson.config.path,
    httpOnly: secJson.config.cookies.httpOnly,
    secure: true,
    maxAge: secJson.config.duration.ttl * 1000
  },
  // store: new RedisStore(redisOptions),
  store: new MongoStore({
    mongooseConnection: security.database,
    ttl: (secJson.config.duration.ttl)
  }),
  name: 'spartan'
}

_spartan treats the value of the variable SESSION_SECRET as privileged information and as such is stored & accessed in accordance with other secrets. You may wish to generate a random, hard-to-guess session secret (using a module like UUID/v4), but this functionality is not currently part of the sessions module.

AVAILABLE METHODS

Module Instantiation

method name description params returns
sessioner sets up a new session with parameters/configurations provided in security.json N/A session(options) or Error

USAGE

// in app.js
let sess = security.sessions.sessioner

EXAMPLE

  app.use(sess())

Destroy Cookies

method name description params returns
cookieMonster destroys a cookie (response, options* Object, callback function) Error

* options = { name : name of cookie, options: { params used to create cookie}, optional }

USAGE

let cookieMonster = security.sessions.cookieMonster
app.get('/route', cookieMonster(response, {name: badCookie, options: {path: '/', secure: 'false'}}, (err) => {
  if (err) {
    next(err)
  }
}), (request, response, next) => {
  ... // do some thing
})

Create Cookies

method name description params returns
cookieMaker creates a cookie with provided params && settings from security.json (request, response, options** Object, callback function) configured cookie or Error

** options = { name : name of cookie, value : value of cookie options: { additional configs, e.g, path, domain}, optional }

_spartan will overload any settings provided in the options object with those that are provided in security.json (e.g. httpOnly, secure, same-site); It is recommended that you do not set the ‘domain’ property, however, if you choose to do so, _spartan will not add ‘Host’ or ‘Secure’ flags to the cookies

USAGE

let cookieMaker = security.sessions.cookieMaker
app.get('/route', cookieMaker(request, response, {name: goodCookie, value: 'Cookie nom nom nom', options: {path: '/', secure: 'false'}}, (err) => {
  if (err) {
    next(err)
  }
}), (request, response, next) => {
  ... // do some thing
})

Session Integrity

method name description params returns
csrf creates a csrf token to session integrity (options*** Object, callback function) CSRF module function or Error

*** options = { cookie : true or false, Boolean }

USAGE

let csrf = security.sessions.csrf
app.use(csrf({cookie: true}))

ERRORS

  • (‘sessions/disabled-by-policy’) => thrown if session management is disabled by policy. To change this, mark sessionPolicy.enabled : true in security.json and then run _spartan --force
  • (‘session/missing-params’) => thrown if either the cookie name or cookie value parameters are missing in the cookieMaker method
  • (‘session/insecure-connection’) => thrown if a secure cookie was requested, but an insecure connection was detected/NO secure server was detected
  • (‘sessions/missing-csrf-options’) => thrown if required configuration object (cookie) was not found in the parameters
  • (‘sessions/option-type-incorrect’) => thrown if a object property type (cookie : true/false) was incorrect