Skip to content
This repository has been archived by the owner on Sep 14, 2022. It is now read-only.

ignoreRoutes as extension of ignoreMethods #75

Closed
pszabo1 opened this issue May 22, 2015 · 9 comments
Closed

ignoreRoutes as extension of ignoreMethods #75

pszabo1 opened this issue May 22, 2015 · 9 comments
Assignees
Labels

Comments

@pszabo1
Copy link

pszabo1 commented May 22, 2015

hey there.
I'm currently making use of the csurf module and having an issue, which I think is interesting for others too and can be fixed very easy:
I do want to use and valide csurf for every method, also for get, head, options, etc. - but I want to specifiy some specific routes, which should not be validated.
My quickfix was to fork your module on my private npm and include the following:

var ignoreRoutes = options.ignoreRoutes === undefined
? []
: options.ignoreRoutes;

if (!ignoreMethod[req.method] &&
ignoreRoutes.indexOf(req.path.replace(new RegExp("/", "g"), "")) === -1) {
verifytoken(req, tokens, secret, value(req));
} 

Now I could use the middleware that way:

var csrfExcludedRoutes = ["someRoute"];

this.app.use(csrf({cookie: true, httpOnly: false, ignoreMethods: [], ignoreRoutes: csrfExcludedRoutes}));

I want to get the csrf-token created, but not validated. Is there another way to do that?

@dougwilson dougwilson self-assigned this May 22, 2015
@billjohnston
Copy link

👍

@crisward
Copy link

crisward commented Jul 2, 2015

For those of you who don't want to fork and create your own npm module, I've found you can achieve the above with code like this.

var csrf  = require('csurf');
var csrfIgnore =['/path/to/ignore/','/another/path/to/ignore/'];
app.use(function(req, res, next){
  if(csrfIgnore.indexOf(req.path)==-1){
    csrf({cookie:true})(req, res, next)
  }else{
    next();
  }
});

Hope that helps someone.

@bookercodes
Copy link

👍

In addition to @crisward workaround, you can also automatically supply the token to templates:

app.use(function validateToken(req, res, next){
  var ignoredRoutes = ["/register"];
  if(ignoredRoutes.indexOf(req.path) == -1){
    csrf()(req, res, next)
    return;
  }
  next();
});
app.use(function createToken(req, res, next) {
  if (typeof req.csrfToken === "function") {
    res.locals.csrfToken = req.csrfToken();
  }
  next();
});

This is really useful when you have a logout link on every page that you want to secure from cross-site request forgery.

It would be nice to have first class support, though.

@bookercodes
Copy link

I am actually just securing forms that do not need securing at the moment (i.e. ones who do not require the user to be authenticated) just because it is much simpler than the solution above - I imagine the aforementioned code will be hard to reason about in a few weeks (curse of knowledge).

@gabeio
Copy link
Member

gabeio commented Jul 2, 2015

csrf doesn't have to be for everything the user does... logout can just be a GET request why does it have to be a POST? why is logging a user out so dangerous/large that it needs to be a POST? I am not disagreeing that being able to ignore routes can be beneficial. but as a side note if you attach csrf after the route you need to not have csrf running on top of that works also ie:

app.use('/api',require('./api')); // this will not be csrf verified
app.use(csrf);
app.use('/theRest',require('./another'));

ignoreRoutes would be extra code for the same thing that already works.

@gabeio
Copy link
Member

gabeio commented Jul 2, 2015

@dougwilson it might be beneficial to have an example of ignoring areas like api's on the README for this module separately from express.

@bookercodes
Copy link

I did not think about that, that is a good solution! Thanks, @gabeio.

csrf doesn't have to be for everything the user does... logout can just be a GET request why does it have to be a POST? why is logging a user out so dangerous/large that it needs to be a POST?

There are numerous reasons why logout should use POST and not a GET. You can read more about that here and here. You can also examine how secure sites implement logout - GitHub, for instance, issues a POST request with a token.

It is also important from a security stand-point depending on the nature of the site.

Imagine an auction site. It would be advantageous for a competing bidder to cause other bidders to be logged out. The delay between being logged out and returning to the auction page might cost the user the auction.

Another example: Imagine a website where a user can only be logged on from one location. An attacker might want to force that user to logout so that he or she can log on (there are numerous ways the attacker could log on).

At the very least, this becomes an inconvenience – it becomes a usability barrier for the user. Imagine an attacker somehow made continuous logout requests from his or her malicious page - so long as the user has the malicious page open in a tab somewhere, every time he or she logged on to the target site, he or she would be instantaneously logged out again… This is one of tens of "attack" vectors. I am sure you can imagine more.

@dougwilson
Copy link
Contributor

@dougwilson it might be beneficial to have an example of ignoring areas like api's on the README for this module separately from express.

Can you elaborate on this or offer a PR, please :)?

@gabeio
Copy link
Member

gabeio commented Jul 2, 2015

basically showing the code that I provided here with a guess more of an example... I will create a PR.

@expressjs expressjs locked as resolved and limited conversation to collaborators May 15, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

6 participants