CSRF with NodeJS and Express 3

In a recent post I took a look at what it took to configure and use the CSRF protection middleware with Express. The article covered Express v2, and in the intervening few months, we’re already at the doorstep of Express v3, and the new version broke my example.

Express v3 did away with the dynamic helpers, so the code making use of them fails. Fortunately, the CSRF module still works fine; you just need to adjust how you’re using it.

Add the CSRF module to the app configuration in the same way as before. For example, on line 11 below, I add the CSRF middleware to the application. One important caveat is the CSRF module depends on the sessions middleware, so you need to configure session support as seen on line 10, and the CSRF middleware has to come after it in the configuration sequence.

app.configure(function(){
  app.set('port', process.env.PORT || 3000);
  app.set('views', __dirname + '/views');
  app.set('view engine', 'jade');
  app.use(express.favicon());
  app.use(express.logger('dev'));
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  app.use(express.cookieParser('your secret here'));
  app.use(express.session());
  app.use(express.csrf());

  app.use(function(req, res, next){
    res.locals.token = req.session._csrf;
    next();
  });

  app.use(app.router);
  app.use(express.static(path.join(__dirname, 'public')));
});

Express v3 eliminated dynamic helpers, preferring instead that developers just use middleware. To facilitate setting variables available during template rendering, we can make use of the res.locals property. On line 13 above, we create a middleware handler which puts the CSRF token generated by the CSRF middleware into a variable called token which will be visible to the templates.

Note: this custom middleware to set a value in res.locals has to come before the app.router middleware defined on line 18, and after the app.csrf() middleware on line 12.

Once this is complete, there will be a variable called token available in all templates. This token should then be placed either into a hidden form field or query string parameter called _csrf on any HTTP request other than a GET,HEAD or OPTIONS request. If any other request type is made and this _csrf value is missing, the middleware will reject the request with an 403 - Forbidden status.

Here is an example of using the value in a Jade template for a form. Note on line 2 I create a hidden field for _csrf and set the value to the token property we created in the custom middleware above :

form(action='/form',method='post')
  input(type='hidden', name='_csrf', value=token)
  label(for='color') Color:
  input(type='text',name='color',size='50')
  button(type='submit') Save

That’s all that is needed to adjust my previous example to work with Express v3.

5 thoughts on “CSRF with NodeJS and Express 3”

  1. Thanks for the update Tim.

    I am curious if you looked at other attack vectors such as XSS?

    I am finishing some new modules and am looking at reducing the attack surface with Xpress and Websockets and would like to see if there are other ways to address security without having to resort to WAF and Proxys like Varnish…

  2. Hi,

    I am using it. csrf token is also generated. it is also correctly executing in csrf middleware. but still I am getting forbidden

  3. Hey,

    This example would generate a new csrf token every time. What would be a valid approach when you are dealing with a single page app? Something that would set a token once and you could store it in a cookie.

Leave a Reply

Your email address will not be published. Required fields are marked *


*