Csurf无效的CSRF令牌Express / Node.js

jac*_*per 5 cookies csrf node.js express mean-stack

我有这种奇怪的行为,就是在我第一次加载页面时才遇到错误,基本上是“ EBADCSRFTOKEN”,我一直在试图弄清楚为什么只有在第一次加载页面时才会发生这种情况,如果我点击刷新并获取一个新的令牌一切正常。

当我删除csurf cookie,单击刷新并获得新令牌时,会发生相同的情况,但是第一次总是失败,我不确定为什么期望的字符串和令牌都不匹配。

一小段代码(我正在使用MEANJS堆栈):

app.use(busboy());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json({limit: '50mb'}));
app.enable('jsonp callback');

var cp = cookieParser;
app.use(cp());

var mStore = new mongoStore({
    db: db.connection.db,
    collection: config.sessionCollection
});

app.use(session({
    secret: config.sessionSecret,
    store: mStore,
    cookie: {httpOnly: false},
    key:config.cookieKey,
}));

app.use(csrf());

//setting up a middleware
var middlewareFiles = [
    'csrf-rule.server.js', 
    'secure-routes.server.js'
];

middlewareFiles.forEach(function(routeSecure){
    require(path.resolve('./app/middleware/'+routeSecure))(app);
});

app.use(function(err, req, res, next) {
    if (!err) return next();
        if(err.code === 'EBADCSRFTOKEN'){
            res.json(484, {data: 'invalid csrf token.'});
        return;
    }
   // Error page
    res.status(500).render('500', {
        error: err.stack
    });
});
Run Code Online (Sandbox Code Playgroud)

中间件:

module.exports = function(app) {
    app.use(function(req, res, next){
        res.cookie('x-xsrf-token', req.csrfToken());
        res.locals.csrftoken = req.csrfToken();
        next();
    });
};
Run Code Online (Sandbox Code Playgroud)

令牌的不同值:

曲奇饼

fgeHcu6v-hgdCMuRjnmE9BYV_QrvrfzwJoeA

req.csrfToken()(在中间件请求中)

fgeHcu6v-hgdCMuRjnmE9BYV_QrvrfzwJoeA

预期(在csurf库中)

fgeHcu6v-T9CuTWL8hVGHMtSskeh0yzqaP0k

令牌(在csurf库中)

fgeHcu6v-hgdCMuRjnmE9BYV_QrvrfzwJoeA

似乎预期的类似于令牌,并且它们在破折号之后有所不同,有什么想法吗?

更新:

基本上,我遵循@shakiba的建议,删除了自定义中间件,然后让csurf库处理它。

我将配置更改为:

app.use(csrf({ cookie: true }));
Run Code Online (Sandbox Code Playgroud)

现在我得到一个名为_csrf的cookie ,现在的问题有所不同,令牌值与库中的秘密令牌相同,因此当库将“秘密令牌”“转换”期望的令牌时,它们不会比赛。

这些是一些示例值:

Cookie BDir8-6hkdy-_YsXNb305IIx

秘密 BDir8-6hkdy-_YsXNb305IIx

代币 BDir8-6hkdy-_YsXNb305IIx

预期的 BDir8-zbwt4-K_Uv8t1TtmxxctkfcMN1M

Ali*_*iba 4

我相信你没有正确使用csurf,csurf为你设置了cookie,你不应该自己设置它,并且它的值与csrfToken()值不同。据我从文档和源代码中了解到, csrfToken() 值是使用 csurf 为 cookie 设置的值生成的,因为它们声明可以减轻 BREACH 攻击。

我制作了更简单的 csurf 版本,它仅使用 cookie,并且不对 BREACH 攻击执行任何操作,因为 BREACH 攻击在我看来是一个独立的问题,应该在独立的模块/库中解决。我将在 github 上分享它,以便您可以使用它(如果您愿意)。

  • 如何在请求中设置令牌?您应该使用“req.csrfToken()”,将其分配给视图局部变量,可以是“res.locals”(如您在中间件中所做的那样),也可以是“res.render(view, locals)”。目前您正在使用 cookie/秘密值作为令牌。 (2认同)