简体   繁体   English

Csurf无效的csrf令牌Express / nodejs

[英]Csurf invalid csrf token Express / nodejs

I have this odd behavior I get an error just the first time my page loads, basically is 'EBADCSRFTOKEN' I've been trying to figure it out why it happens only the first time the page loads, if I hit refresh and get a new token everything works fine. 我有这种奇怪的行为,我第一次加载页面时出现错误,基本上是'EBADCSRFTOKEN'我一直试图弄清楚为什么它只在第一次加载页面时发生,如果我点击刷新并得到一个新的令牌一切正常。

the same scenario happens when I delete the csurf cookie, hit refresh and I get a new token, but the first time always fail I'm not sure why both the expected string and the token don't match. 当我删除csurf cookie,点击刷新并获得一个新令牌时会发生同样的情况,但第一次总是失败我不确定为什么预期的字符串和令牌都不匹配。

a snippet of the code (I'm using MEANJS stack): 一段代码(我正在使用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
    });
});

Middleware: 中间件:

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

Different values for the token: 令牌的不同值:

Cookie 曲奇饼

fgeHcu6v-hgdCMuRjnmE9BYV_QrvrfzwJoeA fgeHcu6v-hgdCMuRjnmE9BYV_QrvrfzwJoeA

req.csrfToken() (in middleware request) req.csrfToken()(在中间件请求中)

fgeHcu6v-hgdCMuRjnmE9BYV_QrvrfzwJoeA fgeHcu6v-hgdCMuRjnmE9BYV_QrvrfzwJoeA

Expected (in csurf library) 预期(在csurf库中)

fgeHcu6v-T9CuTWL8hVGHMtSskeh0yzqaP0k fgeHcu6v-T9CuTWL8hVGHMtSskeh0yzqaP0k

Token (in csurf library) 令牌(在csurf库中)

fgeHcu6v-hgdCMuRjnmE9BYV_QrvrfzwJoeA fgeHcu6v-hgdCMuRjnmE9BYV_QrvrfzwJoeA

seems like the expected is similar to the token and they differ just after the dash, any ideas? 似乎预期的类似于令牌,他们在破折号之后有所不同,任何想法?

UPDATE: 更新:

Basically, I followed @shakiba recommendation I removed my custom middleware and I let the csurf library handle it. 基本上,我遵循@shakiba建议我删除了我的自定义中间件,我让csurf库处理它。

I changed the configuration to: 我将配置更改为:

app.use(csrf({ cookie: true }));

now I get a cookie named _csrf , now the issue is a little bit different, the token value is the same as the secret token in the library, so when the library "converts" the secret token to be the expected token they don't match. 现在我得到一个名为_csrf的cookie,现在问题有点不同,令牌值与库中的秘密令牌相同,所以当库“转换”秘密令牌成为预期令牌时,他们不会比赛。

These are some example values: 这些是一些示例值:

Cookie BDir8-6hkdy-_YsXNb305IIx Cookie BDir8-6hkdy-_YsXNb305IIx

Secret BDir8-6hkdy-_YsXNb305IIx 秘密 BDir8-6hkdy-_YsXNb305IIx

Token BDir8-6hkdy-_YsXNb305IIx 令牌 BDir8-6hkdy-_YsXNb305IIx

Expected BDir8-zbwt4-K_Uv8t1TtmxxctkfcMN1M 预计 BDir8-zbwt4-K_Uv8t1TtmxxctkfcMN1M

I believe you are not using csurf correctly, csurf sets the cookie for you, you should not set it yourself, and its value is different from csrfToken() value. 我相信你没有正确使用csurf,csurf为你设置cookie,你不应该自己设置它,它的值与csrfToken()值不同。 As far as I understand from docs and source code csrfToken() value is generated using the value that csurf sets for the cookie, as they state to mitigate BREACH attack. 据我所知,从文档和源代码中可以看出csrfToken()值是使用csurf为cookie设置的值生成的,因为它们声明可以缓解BREACH攻击。

I have made simpler version of csurf that only uses cookies and does not do anything about BREACH attack, because BREACH attack looks to me to be an independent concern that should be addressed in an independent module/library. 我已经制作了更简单的csurf版本,它只使用cookie而且没有对BREACH攻击做任何事情,因为BREACH攻击看起来是一个应该在独立模块/库中解决的独立问题。 I will share it on github so you can use it if you like. 我将在github上分享它,如果你愿意,你可以使用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM