Node.js use csurf conditionally with express 4
Asked Answered
A

2

8

I try to use csurf on just a few routes in my express app. that's the approach:

var express       = require('express');
var session       = require('express-session');
var csrf          = require('csurf');

// some more stuff

var csrfExclusion = ['/myApi','/unsecure'];

var app   = express();

var conditionalCSRF = function (req, res, next) {  
  if (csrfExclusion.indexOf(req.path) !== -1){
    next();
  }
  else{
    csrf();
  }
});

app.use(conditionalCSRF);

even tried:

var conditionalCSRF = function (req, res, next) {  
  if (csrfExclusion.indexOf(req.path) !== -1){
    next();
  }
  else{
    csrf(req, res, next);
    next();
  }
});

and

var conditionalCSRF = function (req, res, next) {  
  if (csrfExclusion.indexOf(req.path) !== -1){
    next();
  }
  else{
    csrf();
    next();
  }
});

But this gives me an error: Object # has no method 'csrfToken'

How can I use csurf conditionally. The documentation only gives information to use it on all routes in the express app with

app.use(csrf());

But that's not what I want, I want to exclude some route...

kindly... martin

UPDATE:

finally it works. I did the following:

app.use(function(req, res, next){
  if (csrfExclusion.indexOf(req.path) !== -1) {
  next();
}
  else {
  csrf()(req, res, next);
});

This adds the csrf middleware conditionally. But I really think it's kind of strange to call it like this:

csrf()(req, res, next);

I even do not get the syntax...

Antonina answered 28/7, 2014 at 9:24 Comment(1)
Thank you for sharing your findings, you could have also written a separate answer for that. In any case, I would like to share that currently there are cases where it seems impossible to exempt from csrf. Open issue: github.com/expressjs/csurf/issues/10#issuecomment-232501314Thole
R
6

According to this you need to split it up into two routers, one using csurf and one not. You'd then apply the middleware to the router instead of the app.

var routes = express.Router();
var csrfExcludedRoutes = express.Router();

routes.use(csrf());

routes.get('/', function(req, res) {
    //has req.csrfToken()
});

csrfExcludedRoutes.get('/myApi', function(req, res) {
    //doesn't have req.csrfToken()
});
Rackrent answered 28/7, 2014 at 10:45 Comment(2)
thanks for the link... this might work as well.. I use the described solution now...Antonina
I could not get this suggested solution to work, but the one described by the original poster in his update did the trick.Thigmotaxis
O
2

This is an old thread but I stumbled across it and thought I'd try to address the question that @marshro brings up about the oddity of calling csrf()(req, res, next) in the middleware.

What's happening here is that csurf returns a function from the require statement that is itself used to build a middleware function with some optional configuration parameters.

The call to csrf() used in your middleware above builds the middleware function with default options for EVERY incoming request that needs csrf protection. If you really want to use this approach you DO have an opportunity to make a simple change to make your solution more efficient a very small restructuring to build the middleware once:

// 1. Build the csrf middleware function 'csrfMw' once.
var csrfMw = csrf();          

app.use(function(req, res, next){
    if (csrfExclusion.indexOf(req.path) !== -1) {
        next();
    } else {
        // 2. Use the middleware function across all requests.
        csrfMw(req, res, next);  
    }
);

This said - when you have the opportunity you might want to check out the docs again - there are two methods recommended for avoiding this approach. The first sets up middleware csrfProtection and applies it to select routes. The second sets up two routers as @ben-fortune mentioned above - one that applies csrf to everything and one that does not. Both would be more efficient than having an exclusions condition.

All this said - I can see the case to have an exclusions list and may use your approach if I don't have the time to split apart routes manually. ;)

Om answered 8/4, 2016 at 15:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.