在Web开发中,CSRF(跨站请求伪造)是一种常见的攻击方式,攻击者通过诱导用户在已登录的网站上执行非预期的操作。为了防止这种攻击,通常会使用CSRF令牌。
会话Cookie:会话Cookie是一种存储在用户浏览器中的小型数据片段,用于跟踪用户的会话状态。它们通常在用户关闭浏览器时失效。
CSRF令牌:CSRF令牌是一个随机生成的唯一值,服务器将其嵌入到表单中,用户在提交表单时,服务器会验证这个令牌是否匹配,以确保请求是由合法用户发起的。
使用会话Cookie作为CSRF令牌并不是一个好的做法,原因如下:
为了更好地保护Web应用免受CSRF攻击,建议使用专门的CSRF令牌,而不是依赖会话Cookie。以下是一个简单的实现示例:
const express = require('express');
const crypto = require('crypto');
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.urlencoded({ extended: true }));
// 生成CSRF令牌
function generateCSRFToken() {
return crypto.randomBytes(16).toString('hex');
}
// 设置CSRF令牌到会话
app.use((req, res, next) => {
if (!req.session.csrfToken) {
req.session.csrfToken = generateCSRFToken();
}
next();
});
// 渲染表单页面
app.get('/form', (req, res) => {
res.send(`
<form action="/submit" method="POST">
<input type="hidden" name="_csrf" value="${req.session.csrfToken}">
<button type="submit">Submit</button>
</form>
`);
});
// 处理表单提交
app.post('/submit', (req, res) => {
if (req.body._csrf !== req.session.csrfToken) {
return res.status(403).send('Invalid CSRF token');
}
res.send('Form submitted successfully');
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CSRF Form</title>
</head>
<body>
<form action="/submit" method="POST">
<input type="hidden" name="_csrf" id="csrfToken">
<button type="submit">Submit</button>
</form>
<script>
fetch('/form')
.then(response => response.text())
.then(html => {
const parser = new DOMParser();
const doc = parser.parseFromString(html, 'text/html');
const csrfTokenInput = doc.getElementById('csrfToken');
csrfTokenInput.value = csrfTokenInput.value;
document.body.innerHTML = doc.body.innerHTML;
});
</script>
</body>
</html>
通过这种方式,可以确保CSRF令牌的安全性和不可预测性,从而有效防止CSRF攻击。
领取专属 10元无门槛券
手把手带您无忧上云