lusca
lusca copied to clipboard
Support CSRF black/white listing on URL params
We have a scenario where our API is consumed by an Angular app using JWT with cookies for authentication and as such we have CSRF enabled.
Our server also supports validating the access token if provided as a url query parameter. We'd like to be able to blacklist (not perform CSRF) API calls when the access token is provided this way. This will enable us to expose the same API for REST clients.
Could the CSRF blacklist/whitelist feature compare against the req.originalUrl instead of just req.path?
At present it performs a simple indexOf comparison the request to ensure the path starts with the blacklist/whitelist entry. Ideally this could support a regex comparison against the req.originalUrl.
This way we could bypass CSRF when the url contains a JWT access token in the query string by specifying something like:
{
csrf: {
angular: true,
blacklist: '\\[?&]access_token=[A-Za-z0-9\\-_=]+\\.[A-Za-z0-9\\-_=]+\\.[A-Za-z0-9\\-_=]+'
}
}
Hi @mjy78 , As I understand, you'd like two features added:
- option to compare against req.originalUrl instead of req.path
- regex option as opposed to string/array Can you confirm?
That's correct.
Although we've since worked around the need for this feature by initialising lusca with csrf: false
, then defining a separate middleware that explicitly calls lusca.csrf, but only after checking that the query string doesn't contain the access token...
var csrf = lusca.csrf({
angular: true
});
app.use(lusca({
csrf: false, // Only for web based (AngularJS app) clients - see conditional middleware below
xframe: 'SAMEORIGIN',
hsts: {
maxAge: 31536000, //1 year, in seconds
includeSubDomains: true,
preload: true
},
xssProtection: true
}));
// To allow non-browser clients to make use of the API without CSRF validation complicating things,
// we don't perform CSRF validation whenever the "access_token" query parameter is included in
// the url.
var conditionalCSRF = function (req, res, next) {
if (!req.query.access_token) {
csrf(req, res, next);
} else {
next();
}
}
app.use(conditionalCSRF);