Pages

Tuesday, December 31, 2013

node.js, express.js & the redis sessions store with encryption

node.js

For those of you that are already familiar with the wonderful language that is node.js please read ahead. For those that are not, lets close the gap.

Node.js is a platform built on Chrome's JavaScript runtime for easily building fast, scalable network applications. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices.

express.js

Much like any other web or interpreted language (Ruby, PHP, Python etc), node.js also has existing framworks to cut down development time. express.js is one of those frameworks.

One of the very nice things about express.js is performing operations such as the following:

$ npm install -g express
$ express --sessions --css stylus --ejs myapp
     
  create : myapp
  create : myapp/package.json
  create : myapp/app.js
  create : myapp/public
  create : myapp/public/javascripts
  create : myapp/public/images
  create : myapp/public/stylesheets
  create : myapp/public/stylesheets/style.styl
  create : myapp/routes
  create : myapp/routes/index.js
  create : myapp/views
  create : myapp/views/index.ejs

install dependencies:

$ cd myapp && npm install

run the app:

$ node app

What the above output performs is create a new project (in the exampled named 'myapp') that contains a very simple web application complete with stylesheets, HTML & the code necessary to run a web server application.

In addition their repo contains numerous project examples to help you get your own project up and running quickly.

redis

If your not familiar with redis perhaps an alternate tool such as memcached is more familiar. Both are software which can be used to serve content quickly and efficiently as they do not utilize disk writes etc and instead store the key/value data within memory making them extremely fast and useful for things such as 'session storage'.

Now that we have some background on redis, lets go back to talking about express.js. The express.js framework is simply a high level API providing access to the connect.js middleware for node.js.

sessions

This particular concent is in its simplest form the earliest method of allowing for persistant variable use within the HTTP 1.0 protocol. Because HTTP is considered a 'stateless' protocol developers needed a way to keep information from one page request to the next.

Use of sessions within the express.js framework is very easy. See below for a simple example of its use within the project we created earlier.

app.use(express.cookieParser());
app.use(express.session({secret: 'kung fu'}));

connect.js custom session store

There are many reasons one might want to use a custom session store. From the connect.js session manual:

Warning: connection.session() MemoryStore is not designed for a production environment, as it will leak memory, and will not scale past a single process.

As noted to ensure the scalability and stability of any web application requiring use of sessions it is best to utilize a custom session store.

Not to worry there are plenty of quality session store middleware modules we can choose from.

connect-redis-crypto

The connect-redis-crypto module is based on the connect-redis module which provides a transparent method of getting/setting/destroying server side sessions from connect.js middlware and implemented within the express.js framework.

The reason why connect-redis-crypto exists is because according to OWASP session management recommendations...

The stored information can include the client IP address, User-Agent, e-mail, username, user ID, role, privilege level, access rights, language preferences, account ID, current state, last login, session timeouts, and other internal session details. If the session objects and properties contain sensitive information, such as credit card numbers, it is required to duly encrypt and protect the session management repository.

Now lets see how to use it within our project:

var express = require('express'),
    RedisStore = require('connect-redis')(express);
     
app.use(express.session({
  secret: 'cookie signature secret',
  store: store: new RedisStore({
    secret: 'sessions crypto secret'
  })
}));

Summary

Not everyone is going to require the use of encryption for managing their session data but for those that do my fork of an already great module should be of assistance.

No comments:

Post a Comment