Django 生产环境如何配置 CSRF 和 XSS 防护策略?

文章导读
Django 默认启用 CSRF 中间件和模板自动转义,生产环境配置核心在于修正 HTTPS 代理下的 Cookie 策略,并严格控制模板中的自动转义绕过行为。
📋 目录
  1. 快速处理思路
  2. 为什么会这样
  3. 分步处理
  4. 怎么验证是否生效
  5. 常见坑
  6. 常见问题
  7. 参考来源
A A

Django 默认启用 CSRF 中间件和模板自动转义,生产环境配置核心在于修正 HTTPS 代理下的 Cookie 策略,并严格控制模板中的自动转义绕过行为。

先说结论:Django 安全配置依赖默认中间件生效,生产环境必须针对 HTTPS 和反向代理调整 Cookie 安全标志及信任源列表。

  • 先判断:确认应用是否部署在 HTTPS 环境下,以及是否经过 Nginx 等反向代理。
  • 优先做:在 settings.py 中设置 CSRF_COOKIE_SECURE 和 SESSION_COOKIE_SECURE 为 True,并配置 CSRF_TRUSTED_ORIGINS。
  • 再验证:通过浏览器开发者工具检查响应头 Cookie 属性,并测试跨域 POST 请求是否被拦截。

快速处理思路

生产环境不需要额外安装插件即可启用基础防护,重点在于修改 settings.py 配置项以适应 HTTPS 协议。

# settings.py 关键配置片段
SECURE_SSL_REDIRECT = True
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
CSRF_TRUSTED_ORIGINS = ['https://yourdomain.com']
SECURE_HSTS_SECONDS = 31536000

如果前端使用 AJAX 请求,需要确保请求头携带 X-CSRFToken,且 Cookie 配置允许跨域读取。

为什么会这样

Django 默认安全策略针对开发环境设计,直接迁移到 HTTPS 生产环境会导致 Cookie 传输不安全或 CSRF 校验失败。

CSRF 防护依赖 Cookie 中的 token 与请求中的 token 匹配,如果 Cookie 未设置 Secure 标志,HTTPS 页面可能通过 HTTP 泄露 Cookie。XSS 防护依赖模板引擎的自动转义,手动关闭转义会引入注入风险。反向代理会改变请求的 Host 和协议头,导致 Django 认为请求来源不可信而拒绝服务。

分步处理

步骤 1:强制 HTTPS 与 Cookie 安全标志

适用场景:所有生产环境。操作动作:在 settings.py 中开启 SECURE_SSL_REDIRECT 和 COOKIE_SECURE 选项。风险边界:开启后无法通过 HTTP 访问,需确保 SSL 证书有效。

Django 生产环境如何配置 CSRF 和 XSS 防护策略?

步骤 2:配置信任源列表

适用场景:使用 Nginx、Apache 或负载均衡器时。操作动作:将生产域名加入 CSRF_TRUSTED_ORIGINS 列表。验证结果:POST 请求不再返回 403 Forbidden。风险边界:列表中包含非信任域名会导致 CSRF 防护失效。

步骤 3:检查模板转义

适用场景:渲染用户提交内容的页面。操作动作:搜索代码库中的 |safe 过滤器和 mark_safe 函数。验证结果:确认仅受信任内容被标记为安全。风险边界:滥用 |safe 会导致 XSS 漏洞。

怎么验证是否生效

使用浏览器开发者工具 Network 面板检查响应头 Set-Cookie,确认包含 Secure 和 HttpOnly 标志。

使用 curl 命令测试 CSRF 保护:

curl -X POST https://yourdomain.com/login/ -d "username=test&password=test"

未携带 CSRF token 时,Django 应返回 403 状态码。检查页面源码,确认用户输入内容被 HTML 实体转义(如 < 变为 &lt;)。

Django 生产环境如何配置 CSRF 和 XSS 防护策略?

常见坑

1. AJAX 请求未携带 Token:前端 JavaScript 需要自动从 Cookie 读取 CSRF token 并添加到请求头 X-CSRFToken。

2. 多级域名 Cookie 共享:如果子域名需要共享登录态,需配置 SESSION_COOKIE_DOMAIN,但会增加 CSRF 风险。

3. 混合内容警告:HTTPS 页面加载 HTTP 资源会导致浏览器拦截,间接影响安全策略执行。

4. 第三方登录回调:OAuth 回调地址必须在 CSRF_TRUSTED_ORIGINS 中,否则登录流程会中断。

常见问题

AJAX 请求如何获取 CSRF token?

Django 模板提供的 csrftoken Cookie 可直接被 JavaScript 读取,需在请求头中手动添加 X-CSRFToken 字段。

开启 SECURE_SSL_REDIRECT 后无法访问怎么办?

检查反向代理是否正确传递 X-Forwarded-Proto 头,并设置 USE_X_FORWARDED_HOST = True。

是否需要额外安装 CSP 中间件?

Django 默认不包含内容安全策略(CSP),如需防御 XSS 建议引入 django-csp 库并在 Nginx 层配置 Header。

参考来源

  • Django Documentation, Security in Django, https://docs.djangoproject.com/en/stable/topics/security/
  • Django Documentation, Deployment checklist, https://docs.djangoproject.com/en/stable/howto/deployment/checklist/