Kamixitong/docs/CSRF_CONFIG_GUIDE.md
2025-12-12 11:35:14 +08:00

5.9 KiB
Raw Permalink Blame History

🔐 CSRF保护配置指南

📋 问题描述

KaMiXiTong系统在移除csrf.exempt(api_bp)所有API请求都受到CSRF保护导致前端API调用返回400错误。

错误表现

Failed to load resource: the server responded with a status of 400 (BAD REQUEST)
API request failed: Error: 400: BAD REQUEST

解决方案

当前配置

我们已恢复对API蓝图的CSRF豁免

# app/__init__.py
from app.api import api_bp
app.register_blueprint(api_bp, url_prefix=f'/api/{app.config["API_VERSION"]}')
csrf.exempt(api_bp)  # 对API豁免CSRF

配置原理

1. API豁免CSRF的原因

  • API有独立的认证机制 - 需要登录token或session
  • 非浏览器端调用 - API主要供前端AJAX调用
  • CORS已配置 - 跨域访问已控制
  • 其他安全措施 - 频率限制、参数验证等

2. Web表单保持CSRF保护

  • 浏览器表单 - 仍然需要CSRF token
  • 用户登录 - 需要CSRF保护
  • 敏感操作 - 需要额外验证

🔒 安全策略

分层防护

组件 CSRF保护 其他保护措施
API接口 豁免 登录验证、频率限制、参数验证
Web表单 启用 CSRF token、表单验证
第三方回调 豁免 签名验证、IP白名单

详细配置

API安全措施

  1. 登录验证
@api_bp.route('/licenses', methods=['POST'])
@require_login  # 要求登录
def create_license():
    # 需要管理员权限
  1. 频率限制
@api_bp.route('/licenses/generate', methods=['POST'])
@rate_limit(limit=10, window=3600)  # 每小时10次
def generate_license():
  1. 参数验证
from flask_wtf import FlaskForm
from wtforms import IntegerField, StringField

class LicenseForm(FlaskForm):
    product_id = StringField('产品ID', validators=[DataRequired()])
    valid_days = IntegerField('有效天数', validators=[DataRequired()])

Web表单CSRF保护

  1. 模板中自动包含CSRF token
<form method="POST">
    {{ csrf_token() }}  # Flask-WTF自动添加
</form>
  1. AJAX请求添加CSRF token
// 获取CSRF token
const csrfToken = document.querySelector('meta[name="csrf-token"]').content;

// AJAX请求头
fetch('/api/data', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
        'X-CSRFToken': csrfToken
    },
    body: JSON.stringify(data)
});

🛡️ 安全检查

已实施的安全措施

  • API豁免CSRF当前配置
  • Web表单保持CSRF保护
  • API需要登录验证
  • API频率限制
  • 参数验证
  • CORS配置
  • 数据库约束

需要注意的安全点

  1. 不要在API中信任客户端数据

    • 始终验证输入参数
    • 使用参数化查询
    • 实施白名单验证
  2. API访问控制

    • 确保所有API都需要认证
    • 实施基于角色的访问控制
    • 记录API访问日志
  3. 第三方接口

    • 支付宝回调等需要单独处理
    • 使用签名验证
    • 限制IP白名单

🔧 配置选项

选项1: API豁免CSRF推荐

# 当前配置 - API豁免CSRF
csrf.exempt(api_bp)

# 优点
- 简单可靠
- 不影响前端开发
- API有其他安全措施

# 适用场景
- 内部API系统
- 有完整认证机制
- 前后端分离架构

选项2: API启用CSRF

# 启用API CSRF保护
# 需要修改前端代码

# 前端需要
1. 获取CSRF token
2. 在每个POST/PUT/DELETE请求中添加token
3. 处理token过期逻辑

# 缺点
- 复杂的前端实现
- 需要处理token刷新
- 可能影响API可用性

选项3: 混合模式

# 仅对敏感API启用CSRF
from flask_wtf.csrf import csrf_exempt

# 部分API豁免
csrf.exempt(api_bp)

# 特定端点保护
@api_bp.route('/sensitive', methods=['POST'])
@csrf.protect()  # 强制启用CSRF
def sensitive_operation():

🚀 验证配置

测试API豁免CSRF

# 直接调用API不需要CSRF token
curl -X POST http://localhost:5000/api/v1/licenses \
  -H "Content-Type: application/json" \
  -d '{"product_id": "test", "valid_days": 30}'

# 应该返回401未认证而不是400CSRF错误

测试Web表单CSRF

<!-- 不包含CSRF token的表单应该被拒绝 -->
<form method="POST">
    <input type="text" name="username">
    <input type="password" name="password">
    <!-- 没有{{ csrf_token() }} -->
    <button type="submit">登录</button>
</form>

<!-- 返回400错误 -->

📊 风险评估

当前配置的安全性

风险类型 风险等级 缓解措施
CSRF攻击 🟡 中等 API有认证机制
XSS攻击 🟢 输入转义、输出编码
SQL注入 🟢 参数化查询
会话劫持 🟡 中等 HTTPS、Secure Cookie
API滥用 🟡 中等 频率限制、认证

建议的安全增强

  1. 启用HTTPS - 防止中间人攻击
  2. 使用JWT token - 替代session认证
  3. API签名验证 - 对敏感操作增加签名
  4. IP白名单 - 限制API访问来源
  5. 审计日志 - 记录所有API调用

📞 支持与联系

常见问题

Q: API返回400错误怎么办 A: 检查是否恢复了csrf.exempt(api_bp)配置

Q: 如何为特定API启用CSRF A: 使用@csrf.protect()装饰器

Q: Web表单CSRF验证失败 A: 确保模板包含{{ csrf_token() }}

Q: AJAX请求如何添加CSRF token A: 从meta标签获取token并添加到请求头

工具脚本

  • scripts/fix_logging.py - 修复日志问题
  • scripts/health_check.py - 健康检查

相关文档


更新时间: 2025-12-12 配置状态: API豁免CSRFWeb表单保护