3

来自http://sporcic.org/2012/10/csrf-with-nodejs-and-express-3

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

为了利用上述保护,这是否意味着我应该_csrf在我的所有表单中放置隐藏的隐藏输入,包括仅限管理员的页面?

4

2 回答 2

8

One option is to add a hidden input field to all your forms as you mention. But according to the Express docs on csrf:

The default value function checks req.body generated by the bodyParser() middleware, req.query generated by query(), and the "X-CSRF-Token" header field.

So depending on your client side framework, you could also use the query string or the X-CSRF-Token alternatives.

The point remains that you need to:

  • pass the _.csrf token from Express to your client side
  • return the _.csrf token from the client side back to Express on all your state mutating reqs (POST/PUT/DELETE) so Express can compare it against the req.session._csrf to complete the cycle.

For example if your client side is in Angular, the $http module offers csrf protection by default, looking for a cookie called XSRF-TOKEN and returning this value on all state mutating requests (POST/PUT/DELETE) through a header calledX-XSRF-TOKEN. This is an unlucky coincidence, because the name differs from the header name where Express looks for it, which is X-CSRF-TOKEN (notice -XSRF- vs. -CSRF-).

To overcome this you need to

Step 1: On the Express side augment the default value function of the CSRF middleware to look for the token value in the X-XSRF-TOKEN header, in addition to all other default places:

app.use(express.csrf({value: function(req) {
    var token = (req.body && req.body._csrf) || 
        (req.query && req.query._csrf) || 
        (req.headers['x-csrf-token']) || 
        // This is the only addition compared to the default value function
        (req.headers['x-xsrf-token']);
    return token;
    }
});

Step 2: On the Express side again set the token value added by the CSRF middleware under req.session._csrf in the cookie that Angular will look for, using a custom middleware:

app.use(function(req, res, next) {
    req.cookie('XSRF-TOKEN', req.session._csrf);
    next();
});

Now Angular will find it and include it in the X-XSRF-TOKEN header without any further action.

于 2014-04-10T09:42:30.507 回答
1

在那篇文章的后面,作者解释说,这会向所有应该包含在隐藏输入字段中的模板公开一个“令牌”属性。

请注意他的玉示例中的第二行:

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
于 2013-10-24T13:20:50.677 回答