2

当我将 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 中设置“信任代理”:

来源: npm express-session

我目前在本地运行该站点,所以它不是 HTTPS。我想知道secure:true与未通过 csrf 测试有何关系?

4

1 回答 1

3

由于提供的代码示例不包括表单的创建,我假设您正确地包含了该_csrf值。或者您使用 JavaScript 设置相应的标头。

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

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

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

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

现在至于它在 HTTPS 上失败的部分原因。

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

根据OWASP 页面

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

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

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

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

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

注意!作为旁注,如果您更感兴趣,我建议您阅读OWASP CSRF 缓解备忘单。或者我关于Node.js Web 应用程序安全的书,其中包括 CSRF 和使用 Node.js 实现的各种缓解方法。

于 2016-01-04T18:23:15.903 回答