I am trying to implement CSRF protection in an app built using node.js using the express.js framework. The app makes abundant use of Ajax post calls to the server. I understand that the connect framework provides CSRF middleware, but I am not sure how to implement it in the scope of client-side Ajax post requests.
There are bits and pieces about this in other Questions posted here in stackoverflow, but I have yet to find a reasonably complete example of how to implement it from both the client and server sides.
Does anyone have a working example they care to share on how to implement this? Most of the examples I have seen, assume you are rendering the form on the server-side and then sending it (along with the embedded csrf_token form field) to the client-side. In my app, all content is rendered on the client-side (including templates) via Backbone.js. All the server does is provide values in JSON format, which are utilized by various Models in Backbone.js on the client-side. By my understanding I would need to retrieve the csrf_token via ajax first before it can be used. However, I am concerned this may be problematic from a security standpoint. Is this a valid concern?
It can be done by adding meta
tag for CSRF token and then pass CSRF token with every Ajax request
Add CSRF middleware
app.use(express.csrf());
app.use(function (req, res, next) {
res.locals.token = req.session._csrf;
next();
});
You can pass a CSRF token to the client side via, say, a meta tag. For ex, in Jade
meta(name="csrf-token", content="#{token}")
jQuery has a feature called ajaxPrefilter, which lets you provide a callback to be invoked every Ajax request. Then set a header using ajaxPrefilter.
var CSRF_HEADER = 'X-CSRF-Token';
var setCSRFToken = function (securityToken) {
jQuery.ajaxPrefilter(function (options, _, xhr) {
if (!xhr.crossDomain) {
xhr.setRequestHeader(CSRF_HEADER, securityToken);
}
});
};
setCSRFToken($('meta[name="csrf-token"]').attr('content'));