如果会话cookie是安全的,则CSURF无法工作

3

我很困惑,当我将cookie设置为安全时,node.js的csrf功能无法正常工作。

//Load Cooike Parser
app.use(cookieParser(secret));
//Load Session Store
app.use(require('express-session')({
    secret:secret,
    cookie:{
        maxAge: 1000 * 60 * 60 * 24, // 1 day,
        secure: true,
        httpOnly: true
    },
    store: sessionStore
}));
//Load POST data parser
//Form sent should be in JSON format
app.use(bodyParser.json());

//Initiate CSRF on middleware
//set the CSRF cookie Header
app.use(csrf());
app.use(function(req,res,next){
    res.cookie('XSRF-TOKEN',req.csrfToken());
    next();
});

这个设置使用MongoDB来存储会话数据。阅读express-session文档时,我发现了这个内容...
请注意,secure:true是一个推荐的选项。但是,它需要一个启用https的网站,即安全cookie需要HTTPS支持。如果设置了"secure"并且您通过HTTP访问站点,则不会设置cookie。如果您将node.js放在代理后面并且使用secure:true,则需要在express中设置"trust proxy"。
来源: npm express-session 我目前正在本地运行网站,因此它不是HTTPS。我想知道的是,secure:true如何与未通过csrf测试相关联?
1个回答

4

由于提供的代码示例没有涵盖表单创建过程,我将假设您正确地包含了_csrf值。或者您使用JavaScript设置了相应的标头。

让我们首先解释为什么不应该执行res.cookie('XSRF-TOKEN',req.csrfToken());

csurf模块的默认方式是在运行req.csrfToken()时生成或返回_csrf令牌,但它还会将此令牌保存在会话中。

如果要使用cookie而不是会话作为存储方法,您应该将cookie: truecookie: cookieOptions作为初始化值传递给csurf,而不是手动设置cookie。

这很重要,因为如果不使用预期的选项参数,则csurf将尝试从会话对象查找令牌值进行验证,这意味着您的cookie设置是无用的。

现在关于为什么在HTTPS上失败的部分。

当您设置secure: true时,它会将带有secure标志的cookie从服务器发送到浏览器。

根据OWASP页面的说法:

安全标志是应用程序服务器在HTTP响应中向用户发送新cookie时可以设置的选项。 安全标志的目的是防止由于以明文传输cookie而被未经授权的人员观察到。

为了实现这个目标,支持安全标志的浏览器仅会在请求发送到 HTTPS网页时使用带有安全标志的cookie。 换句话说,当请求发送到未加密的HTTP请求时,浏览器不会发送已设置安全标志的cookie。

这包括会话令牌cookie,它用于在sessionStore中查找信息。

因此,浏览器不会将会话cookie发送到服务器。服务器创建一个新的空会话,并且因为我们回到了默认的csurf操作方法,它将尝试从空会话中查找令牌。 不会有令牌,因此比较将失败。

顺便提一下,这也意味着您的会话总体上都失败了。

NB! 顺便提一下,如果您更感兴趣,建议您阅读OWASP CSRF防范小抄。 或者阅读我的书,其中包括有关在Node.js中实现的CSRF和各种缓解方法的内容《Node.js Web应用程序安全》


据我所知,由于我使用了不同的会话存储(使用MongoDB作为会话存储),所以我不必在会话初始化中设置cookie属性。这只会让代码更加混乱。 - Mr A
它会导致代码混乱,而且由于您未使用正确的cookie设置,csurf库将不会考虑此问题。 - DeadAlready

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接