如果会话cookie是安全的,则CSURF不起作用

时间:2015-12-22 10:50:25

标签: node.js mongodb session cookies express-session

我很难过,当我将cookie设置为安全时,节点的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。如果设置了安全,并且您通过HTTP访问您的站点,则不会设置cookie。如果你的node.js在代理后面并使用secure:true,你需要在express中设置“trust proxy”:

来源: npm express-session

我目前正在本地运行该网站,因此它不是HTTPS。我想知道secure:true与未通过csrf测试有什么关系?

1 个答案:

答案 0 :(得分:2)

由于提供的代码示例未涵盖表单的创建,因此我将假设您正确包含_csrf值。或者您使用JavaScript设置相应的标题。

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

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

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

这是相关的,因为如果您不使用预期的选项参数,csurf将尝试从会话对象中查找用于验证的令牌值,这意味着您的Cookie设置无效。

现在关于它在HTTPS上失败的部分。

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

根据OWASP page

  

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

     

要实现此目标,支持安全标记的浏览器只会在请求转到 HTTPS页面时发送带有安全标记的 Cookie。换句话说,浏览器将不会发送一个cookie,其中安全标志设置在未加密的 HTTP请求上。

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

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

作为旁注,这也意味着您的会话通常会失败。

NB!作为附注,如果您更感兴趣,我建议您阅读OWASP CSRF mitigation cheatsheet。或者我的关于Node.js Web Application Security的书,其中包括CSRF和Node.js实现的各种缓解方法。