我很难过,当我将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”:
我目前正在本地运行该网站,因此它不是HTTPS。我想知道secure:true
与未通过csrf测试有什么关系?
答案 0 :(得分:2)
由于提供的代码示例未涵盖表单的创建,因此我将假设您正确包含_csrf
值。或者您使用JavaScript设置相应的标题。
让我们首先解释为什么你不应该做res.cookie('XSRF-TOKEN',req.csrfToken());
。
csurf
模块的默认方式是在运行_csrf
时生成或返回req.csrfToken()
令牌,但它也会在会话中保存此令牌。
如果您想使用cookie而不是会话作为存储方法,则应将cookie: true
或cookie: 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实现的各种缓解方法。