ExpressJS中的CSRF保护

时间:2013-10-24 13:12:23

标签: express csrf

来自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隐藏输入,包括仅管理页面?

2 个答案:

答案 0 :(得分:8)

一种选择是在您提到的所有表单中添加隐藏的输入字段。但根据csrf上的Express文档:

  

默认值函数检查由req.body中间件,bodyParser()生成的req.queryquery()标头字段生成的"X-CSRF-Token"

因此,根据您的客户端框架,您还可以使用查询字符串或X-CSRF-Token替代方案。

重点仍然是你需要:

  • _.csrf令牌从Express传递到您的客户端
  • _.csrf令牌从客户端返回到Express上所有状态变异请求(POST / PUT / DELETE),以便Express可以将其与req.session._csrf进行比较以完成循环。

例如,如果您的客户端是Angular,$http模块默认提供csrf保护,查找名为XSRF-TOKEN的cookie并在所有状态变更请求上返回此值(POST / PUT /删除)通过名为X-XSRF-TOKEN的标题。这是一个不吉利的巧合,因为该名称与Express查找的标题名称不同,即X-CSRF-TOKEN(注意-XSRF--CSRF-)。

要克服这一点,你需要

第1步:在Express方面增加CSRF中间件的默认值功能,以查找X-XSRF-TOKEN标头中的标记值,以及所有其他默认位置:< / p>

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;
    }
});

第2步:在Express方面,再次使用自定义中间件设置由Angular将寻找的Cookie中的req.session._csrf下的CSRF中间件添加的令牌值:

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

现在,Angular将找到它,并将其包含在X-XSRF-TOKEN标头中,而无需采取任何进一步措施。

答案 1 :(得分: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