缺少 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
依赖基于 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
});
参考¶
OWASP: 跨站请求伪造 (CSRF)
NPM: lusca
通用弱点枚举:CWE-352.