节点使用 csrf 表示静态



我正在尝试在nodejs,express和React Project中使用csurf。我的 csurf 现在工作正常,但我想仔细检查我是否做对了。

这是我的nodejs路由器和中间件结构:

app.use(cookieParser());
app.use("/api/...") // routes that don't need csrf
app.use("/form/...",csrf({cookie:true})) // form path with csrf middleware
app.use(express.static("/img")) // image folder which doesn't need csrf
app.use(csrf({ cookie: true })); // enable csrf for the rest of the app 
app.all("*", function(req, res, next) {
res.header("X-CSRF-Token", req.csrfToken()); // set csrf to header
return next();
});
app.use(express.static("/SPA")); // frontend project

当前行为:

  1. 当我第一次进入我的 Web 项目时,我的response headers中有X-CSRF-Token: xxxxxset-cookie: _csrf=yyyyy; Path=/

  2. 当我刷新页面时,Cookie: _csrf=yyyyy;出现在request headers部分中。

  3. 当我刷新页面时,X-CSRF-Token更改为不同的值。

  4. 只有X-CSRF-Token值通过 post 请求传递,_csrfcookie 中的值抛出 403。

问题:

一个。我相信设置app.use(csrf({ cookie: true }))是多余的,但是当我将其设置为 false 或删除app.all(...)部分时,应用程序会抛出 403/内部服务器错误。如何解决?

二.X-CSRF-Token每次刷新页面时都会发生变化,这显然是一种正常行为,因为我将其放在标题中,但它是否违背了 csrf 的目的?既然我的项目是SPA,我真的那么在乎吗?

请指出逻辑/行为是否有任何问题?

谢谢。

既然我的项目是SPA,我真的那么在乎吗?

如果客户端应用程序(无论是否SPA)向后端发送一些数据,并且数据直接或间接地更改了后端的状态,例如通过后端代表客户端执行的操作,则存在CSRF漏洞,除非像Angular这样的SPA框架负责CSRF保护,否则您应该关注。使用SPA不会改变CSRF方面的任何东西,它没有帮助,也没有减轻任何作用。

使用cookie解析器中间件,csrf中间件的工作方式如下:

  • 在传入请求中使用预定义的名称检查其 Cookie。如果未找到,则生成一个密钥并将其值(修饰一点)放入响应cookie中,希望在下一个请求中找到它。所以秘密不再是秘密了。

  • 如果未找到cookie并且传入的请求像POST一样发生变化(例如不是GET,HEAD...),则失败,例如发送403并设置cookie。如果像 GET 那样不变异,则处理完成。

  • 如果找到cookie,则检查第二条数据,默认情况下在少数位置,包括具有预定义名称的HTTP标头。如果未找到或找不到且不正确,则传入请求失败。否则,处理完成。

为确保此检查成功,您需要执行 2 个步骤:
- 在后端调用req.csrfToken()获取第二条数据并存储在响应中。您选择将其存储在HTTP标头中,这很好。但是您可以使用任何标头名称。或者,您可以在<head>部分中使用<meta>标签。
- 在客户端上,从后端响应中的上述标头或<meta>标签中获取第二条数据,并将其放入您将要发送的请求中,假设请求正在发生变化,例如 POST、PUT 等。此外,您需要将其放入请求中默认搜索 csrf 中间件的预定义位置之一。

关于您的代码:
1. 缺少负责第二步的客户端代码。
2. 在后端调用csrf({options})函数一次并存储返回值。你已经叫了两次了。返回值,我们称之为retValue,是配置好的 csrf 中间件,根据需要使用它:
app.post(/<path>, retValue, ...req, res, next) => {...
3.至于选项,请设置为httpOnly: true.此外,在生产集secure: true中:

csrf({cookie: {
httpOnly: true,
secure: true
}})

A.我相信设置app.use(csrf({ cookie: true }))是多余的, 但是当我将其设置为 false 或删除app.all(...)部分时,该应用程序 抛出 403/内部服务器错误。如何解决?

通过在路由之前设置app.use(csrf{cookie:true}),可以告诉应用传递通过 csrf 中间件获取的每个请求(高于此命令的请求除外)。这个中间件应该做 3 件事。

首先是设置 csrf cookie,如果它还没有出现的话。此 cookie 是创建/验证 csrf 令牌所需的秘密。

其次是在调用req.csrfToken()时创建新令牌。

第三是验证所有非 GET/HEAD/OPTION 请求的令牌。

了解使用此命令执行的操作也很重要:

app.all("*", function(req, res, next) { res.header("X-CSRF-Token", req.csrfToken());将 csrf 设置为标头返回下一个();});

您的所有请求(获取,发布,放置等)它们都会根据您在cookie中的机密生成新令牌。相同的秘密会生成随机令牌,因为随机盐用于此目的。

因此,如果您删除 app.all 部分req.csrfToken()您将不会生成任何令牌,因此验证将失败。如果您删除app.use(csrf)部分,您将无法验证任何内容,因为该部分进行验证,并且您也无法发行令牌。因为换句话说,中间件将被关闭。因此,您无法删除这两个命令中的任何一个,因为它们用于不同的目的。

B. 每次刷新页面时,x-csrf-Token 都会更改,这显然是一种正常行为,因为我将其放在标题中,但它是否违背了 csrf 的目的?既然我的项目是SPA,我真的那么在乎吗?

csrf 令牌的目的是验证请求是否来自您的网站,否则客户端将只有 cookie,而标头中没有令牌。按链接在您的网站上启动某些操作,但位于其他网站上不会为客户端生成 csrf 令牌。

最新更新