CodeQL 文档

缺少 CSRF 中间件

ID: js/missing-token-validation
Kind: problem
Security severity: 8.8
Severity: error
Precision: high
Tags:
   - security
   - external/cwe/cwe-352
Query suites:
   - javascript-code-scanning.qls
   - javascript-security-extended.qls
   - javascript-security-and-quality.qls

点击查看 CodeQL 代码库中的查询

依赖基于 cookie 的身份验证的网站可能容易受到跨站请求伪造 (CSRF) 的攻击。具体来说,更改状态的请求应包含一个秘密令牌,以便攻击者无法伪造该请求。否则,可以在访问恶意网站的用户不知情的情况下,提交他们不希望提交的请求。

这通常通过在每个请求中嵌入特定于会话的秘密令牌来缓解。然后,将检查此令牌作为额外的身份验证措施。恶意网站应该没有办法猜测要嵌入请求中的正确令牌。

建议

使用 lusca.csrf 等中间件包来防止 CSRF 攻击。

示例

在以下示例中,服务器在执行 changeEmail POST 操作之前对用户进行身份验证

const app = require("express")(),
  cookieParser = require("cookie-parser"),
  bodyParser = require("body-parser"),
  session = require("express-session");

app.use(cookieParser());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(session({ secret: process.env['SECRET'], cookie: { maxAge: 60000 } }));

// ...

app.post("/changeEmail", function(req, res) {
  const userId = req.session.id;
  const email = req.body["email"];
  // ... update email associated with userId
});

这并不安全。攻击者可以代表访问了恶意网站的用户提交 POST changeEmail 请求。由于身份验证在没有用户任何操作的情况下进行,因此即使 changeEmail 操作不是由用户发起的,也会被执行。

可以通过安装 CSRF 防护中间件处理程序来缓解此漏洞

const app = require("express")(),
  cookieParser = require("cookie-parser"),
  bodyParser = require("body-parser"),
  session = require("express-session"),
  csrf = require('lusca').csrf;

app.use(cookieParser());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(session({ secret: process.env['SECRET'], cookie: { maxAge: 60000 } }));
app.use(csrf());

// ...

app.post("/changeEmail", function(req, res) {
  const userId = req.session.id;
  const email = req.body["email"];
  // ... update email associated with userId
});

参考

  • ©GitHub, Inc.
  • 条款
  • 隐私