csrf-protection
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseCSRF Protection
CSRF防护
Defend against Cross-Site Request Forgery attacks using multiple protection layers.
通过多层防护机制抵御跨站请求伪造(Cross-Site Request Forgery)攻击。
Protection Methods
防护方法
| Method | How It Works | Browser Support |
|---|---|---|
| Synchronizer Token | Hidden form field validated server-side | All |
| Double Submit | Cookie + header must match | All |
| SameSite Cookie | Browser blocks cross-origin requests | Modern |
| 方法 | 工作原理 | 浏览器支持 |
|---|---|---|
| 同步令牌(Synchronizer Token) | 通过服务器端验证隐藏表单字段 | 所有浏览器 |
| 双重提交(Double Submit) | Cookie与请求头必须匹配 | 所有浏览器 |
| SameSite Cookie | 浏览器阻止跨源请求 | 现代浏览器 |
Token-Based Protection (Express)
基于令牌的防护(Express)
javascript
const crypto = require('crypto');
function generateToken() {
return crypto.randomBytes(32).toString('hex');
}
// Middleware
app.use((req, res, next) => {
if (!req.session.csrfToken) {
req.session.csrfToken = generateToken();
}
res.locals.csrfToken = req.session.csrfToken;
next();
});
// Validation
app.post('*', (req, res, next) => {
const token = req.body._csrf || req.headers['x-csrf-token'];
if (!token || !crypto.timingSafeEqual(
Buffer.from(token),
Buffer.from(req.session.csrfToken)
)) {
return res.status(403).json({ error: 'Invalid CSRF token' });
}
next();
});javascript
const crypto = require('crypto');
function generateToken() {
return crypto.randomBytes(32).toString('hex');
}
// Middleware
app.use((req, res, next) => {
if (!req.session.csrfToken) {
req.session.csrfToken = generateToken();
}
res.locals.csrfToken = req.session.csrfToken;
next();
});
// Validation
app.post('*', (req, res, next) => {
const token = req.body._csrf || req.headers['x-csrf-token'];
if (!token || !crypto.timingSafeEqual(
Buffer.from(token),
Buffer.from(req.session.csrfToken)
)) {
return res.status(403).json({ error: 'Invalid CSRF token' });
}
next();
});SameSite Cookies
SameSite Cookie配置
javascript
app.use(session({
cookie: {
httpOnly: true,
secure: true,
sameSite: 'strict', // or 'lax'
maxAge: 3600000
}
}));javascript
app.use(session({
cookie: {
httpOnly: true,
secure: true,
sameSite: 'strict', // or 'lax'
maxAge: 3600000
}
}));HTML Form Integration
HTML表单集成
html
<form method="POST" action="/transfer">
<input type="hidden" name="_csrf" value="<%= csrfToken %>">
<button type="submit">Submit</button>
</form>html
<form method="POST" action="/transfer">
<input type="hidden" name="_csrf" value="<%= csrfToken %>">
<button type="submit">Submit</button>
</form>Best Practices
最佳实践
- Apply to all state-changing requests (POST, PUT, DELETE)
- Use SameSite=Strict for sensitive cookies
- Validate Origin/Referer headers
- Never use GET for modifications
- Implement token expiration (1 hour typical)
- Combine multiple defense layers
- 应用于所有状态变更请求(POST、PUT、DELETE)
- 敏感Cookie使用SameSite=Strict
- 验证Origin/Referer请求头
- 绝不要使用GET请求进行数据修改
- 实现令牌过期机制(通常为1小时)
- 组合使用多种防御层
Additional Implementations
其他实现方式
See references/python-react.md for:
- Flask-WTF complete CSRF setup
- React hooks for CSRF token management
- Double submit cookie pattern
查看references/python-react.md获取以下内容:
- Flask-WTF完整CSRF配置
- React hooks管理CSRF令牌
- 双重提交Cookie模式
Common Mistakes
常见错误
- Assuming authentication prevents CSRF
- Reusing tokens across sessions
- Storing tokens in localStorage
- Missing token expiration
- 认为身份认证可以防止CSRF
- 跨会话重复使用令牌
- 将令牌存储在localStorage中
- 未设置令牌过期时间