Nodejs csurf提交一次,token似乎不自动过期?还能重复提交啊,必须手动调用一次req.csrfToken()吗?

Nodejs csurf提交一次,token似乎不自动过期?还能重复提交啊,必须手动调用一次req.csrfToken()吗?

2 回复

Nodejs csurf 提交一次,token似乎不自动过期?还能重复提交啊,必须手动调用一次req.csrfToken()吗?

问题描述

最近在使用 csurf 这个中间件来防止 CSRF 攻击时,发现了一个问题:提交一次表单后,CSRF token 并没有自动失效。这意味着攻击者可以在一段时间内多次重复提交同一个 token。这是否正常?我是否需要手动调用 req.csrfToken() 来生成新的 token?

示例代码

const express = require('express');
const csrf = require('csurf');
const bodyParser = require('body-parser');

const app = express();
app.use(bodyParser.urlencoded({ extended: false }));
app.use(csrf({ cookie: true }));

app.get('/', (req, res) => {
    res.send(`
        <form action="/process" method="POST">
            <input type="hidden" name="_csrf" value="${req.csrfToken()}">
            <button type="submit">Submit</button>
        </form>
    `);
});

app.post('/process', (req, res) => {
    // 处理表单提交
    res.send('Form submitted');
});

app.listen(3000, () => {
    console.log('Server running on port 3000');
});

解释

csurf 中间件默认情况下不会自动使 token 失效。每次请求时,它会从 cookie 或者请求头中读取 token,并进行验证。如果验证通过,它会继续处理请求。

如果你希望每次提交表单后都生成一个新的 token,你需要手动调用 req.csrfToken() 来生成新的 token。例如:

app.get('/', (req, res) => {
    res.send(`
        <form action="/process" method="POST">
            <input type="hidden" name="_csrf" value="${req.csrfToken()}">
            <button type="submit">Submit</button>
        </form>
    `);
});

在这个例子中,每次渲染表单页面时都会重新生成一个新的 token。

结论

csurf 默认行为并不会使 token 自动失效,因此你可能需要手动调用 req.csrfToken() 来生成新的 token,以确保每次提交表单时使用不同的 token。


Csurf 是一个用于 Node.js 应用程序的 CSRF(跨站请求伪造)保护中间件。它默认情况下会为每个会话生成一个 CSRF token,并将其存储在 cookie 中以及作为 csrf-token 字段或 HTTP Header 发送到客户端。

根据你的描述,CSRF token 并没有自动过期,这其实符合预期行为。CSRF token 在会话中是持久化的,直到会话结束。这意味着用户可以多次提交同一个 token,直到会话被销毁。如果你希望在每次请求后都生成一个新的 token,那么需要手动调用 req.csrfToken() 方法来更新 token。

下面是一些基本步骤和代码示例:

  1. 首先确保你已经安装了 csurf 模块:
npm install csurf
  1. 设置 csurf 中间件:
const csrf = require('csurf');
const cookieParser = require('cookie-parser');

app.use(cookieParser());
const csrfProtection = csrf({ cookie: true });

app.get('/form', csrfProtection, (req, res) => {
    res.send(`
        <form action="/process" method="POST">
            <input type="hidden" name="_csrf" value="${req.csrfToken()}">
            <button type="submit">Submit</button>
        </form>
    `);
});

app.post('/process', csrfProtection, (req, res) => {
    res.send("Form processed");
});
  1. 如果你需要每次请求都生成新的 CSRF token,可以显式地调用 req.csrfToken() 来更新它:
app.get('/refresh-csrf', csrfProtection, (req, res) => {
    req.csrfToken(); // 更新 CSRF token
    res.send("CSRF token refreshed");
});

总结来说,CSRF token 默认不会自动过期,除非会话结束。如果你希望每次请求时都生成新的 token,则需要显式调用 req.csrfToken() 方法。

回到顶部