浏览知识库目录

Python

Web 安全与生产配置

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-TypeContent-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,且只信任受控代理。

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 项目