Python
Web 安全与生产配置
发布于 2026年7月22日
Web 安全与生产配置
Django 提供了大量默认安全能力,但只有正确配置并遵循安全开发习惯才能发挥作用。本篇从常见 Web 风险讲到生产环境上线检查。
一、安全原则
- 所有外部输入都不可信,包括表单、URL、请求头、上传文件和第三方回调。
- 身份验证不等于权限验证,每次敏感操作都要检查权限。
- 关键约束同时落在代码和数据库层。
- 数据库账号、云凭据、后台用户都只拥有必要权限。
- 密钥不进入源代码、日志、报错页面和前端资源。
- 依赖和 Django 版本要持续更新安全补丁。
二、CSRF
CSRF 利用已登录用户的浏览器发起非本人意愿的请求。Django 默认中间件会保护不安全方法。
<form method="post">
{% csrf_token %}
...
</form>
不要为了图省事对整个写操作视图使用 csrf_exempt。跨域前端应正确配置可信来源、Cookie 策略和认证方案,而不是关闭保护。
三、XSS
模板变量默认自动转义:
{{ message.content }}
避免直接信任用户富文本:
{{ message.content|safe }}
如果业务允许富文本,应使用成熟的 HTML 清洗库和严格白名单,移除脚本、事件属性、危险 URL 协议等内容。前端用 JavaScript 写入页面时也要避免不安全的 innerHTML。
四、SQL 注入
ORM 查询会参数化输入:
Message.objects.filter(name__icontains=keyword)
使用原生 SQL 时必须传参数,不能拼接用户输入:
Message.objects.raw(
"SELECT * FROM notes_message WHERE name = %s",
[name],
)
列名、排序字段等不能直接参数化,应通过固定白名单映射。
五、权限与越权
典型越权漏洞是用户修改 URL 中的 pk 后访问他人数据:
message = get_object_or_404(
Message,
pk=pk,
owner=request.user,
)
权限检查要覆盖:
- 页面 View。
- DRF API 与对象权限。
- 文件下载接口。
- 管理后台数据范围。
- 批量操作和导出。
- WebSocket 或异步任务入口。
仅在模板中隐藏按钮不构成权限控制。
六、上传文件安全
- 限制文件大小、数量和允许类型。
- 不信任原始文件名,服务端生成存储名。
- 验证实际内容类型,而不只看扩展名。
- 上传目录不能作为可执行脚本目录。
- 私有文件通过鉴权下载接口或短期签名 URL 提供。
- 对高风险文件做病毒扫描和内容处理。
- 设置总容量、用户配额和生命周期清理。
Web 服务器应给用户上传内容设置安全的 Content-Type 与 Content-Disposition。
七、生产关键配置
DEBUG = False
ALLOWED_HOSTS = ["app.example.com"]
CSRF_TRUSTED_ORIGINS = ["https://app.example.com"]
SECURE_SSL_REDIRECT = True
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
SECURE_HSTS_SECONDS = 3600
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
SECURE_HSTS_PRELOAD = False
SECURE_CONTENT_TYPE_NOSNIFF = True
X_FRAME_OPTIONS = "DENY"
注意:
SECRET_KEY从安全的环境变量或密钥服务读取。- 只有 HTTPS 已完全正确时才开启强制跳转和 HSTS。
- HSTS 时间应逐步增加;包含子域和 preload 前确认所有子域都支持 HTTPS。
- 位于反向代理后时,需正确配置代理转发协议和
SECURE_PROXY_SSL_HEADER,且只信任受控代理。
八、Cookie 与会话
SESSION_COOKIE_HTTPONLY = True
SESSION_COOKIE_SAMESITE = "Lax"
CSRF_COOKIE_SAMESITE = "Lax"
根据跨站登录、嵌入页面或独立前端需求选择 SameSite 策略。放宽到 None 时必须使用 Secure,并重新评估 CSRF 风险。
敏感操作可要求重新验证密码;退出、修改密码后应使相关会话或令牌失效。
九、依赖与密钥管理
python -m pip list --outdated
python -m pip check
依赖管理建议:
- 锁定生产依赖版本并可重复构建。
- 订阅 Django 和关键依赖的安全公告。
- 定期扫描已知漏洞。
- 删除不再使用的包,减少攻击面。
- 密钥轮换后确认旧值已失效。
不要把 .env、数据库备份、私钥、云凭据提交到 Git。即使从最新版本删除文件,泄露的密钥仍必须立即轮换。
十、速率限制与审计
登录、注册、找回密码、验证码、搜索和昂贵 API 应进行速率限制。DRF Throttling 可作为基础能力,但高流量或抗攻击场景还应在网关、反向代理或 CDN 层限制。
审计日志记录“谁在何时对什么做了什么”,应覆盖权限变更、批量导出、删除、登录异常和高风险后台操作。审计日志本身也要限制访问并防止随意篡改。
十一、上线检查
python manage.py check --deploy
还要人工确认:
DEBUG=False下 400/403/404/500 页面正常。- HTTPS 跳转、证书续期和代理头正确。
- 数据库、媒体文件和密钥有备份与恢复演练。
- 错误监控、日志、告警和负责人已配置。
- 管理后台受保护,管理员权限最小化。
- 回滚方案经过验证。
十二、本篇检查清单
- 不通过关闭 CSRF 或自动转义解决开发问题。
- 所有敏感对象和文件都执行服务端权限检查。
- 生产关闭 DEBUG,密钥不进入代码仓库。
- 理解 HTTPS、Secure Cookie、HSTS 和代理配置的关系。
- 上线前执行部署检查,并准备备份和回滚。
上一篇:缓存、性能优化与异步任务 | 下一篇:部署 Django 项目