跳到正文
>_ITDITDWeb 安全平台

按框架

Django 安全 — 生产环境加固实务参考

Django 生产环境加固参考:优先级清单,外加 DEBUG/ALLOWED_HOSTS、SECRET_KEY、pip CVE、生产环境安全配置、授权、注入与 SSRF。以防御为主,不含攻击步骤。

发布于 2026-07-02 更新于 2026-07-02 3 分钟阅读

面向:在 Django 上运营应用的人。这里不讲攻击步骤——这是一份用于加固的实务参考:优先级排序的清单、分领域指引、以及自查。要看跨框架的全局,请参阅 按框架的安全防护入口

优先级排序的加固清单

按此表自上而下执行。P0 是前提,P1 是最频繁的事故来源,P2 是持续的运营卫生。

P0 ── 前提(先做这个)

DEBUG=False + ALLOWED_HOSTS / 把 SECRET_KEY 外置 / 快速为 pip 依赖 CVE 打补丁

P1 ── 最主要的事故来源

生产环境安全配置(SSL/HSTS/Cookie)/ 授权(所有者范围)

P2 ── 运营卫生

注入与输出 / CSRF、会话、admin / SSRF、上传

从地基往上加固:P0(前提)→ P1(最主要的事故来源)→ P2(运营卫生)。
优先级控制项具体做法(Django)
P0DEBUG/ALLOWED_HOSTS生产环境 DEBUG=False + 设置 ALLOWED_HOSTS。不暴露详细错误
P0SECRET_KEY来自环境,不放在代码/仓库。泄露时轮换
P0pip 依赖 CVE用 pip-audit / osv-scanner 监控;以运行中的版本判定,快速打补丁
P1生产环境安全配置SECURE_SSL_REDIRECTSECURE_HSTS_SECONDSSESSION_COOKIE_SECURECSRF_COOKIE_SECURESECURE_CONTENT_TYPE_NOSNIFF
P1显式授权需要登录 + 权限 + filter(user=request.user) 以做所有者范围
P2注入/输出通过 ORM 绑定。避免 raw()/extra() 拼接。不要把输入传给 mark_safe/`
P2CSRF/会话/admin不要关闭 CSRF(默认)。限制 admin 的暴露
P2SSRF/上传服务端取回用允许列表 + 阻断内部 IP。校验上传,存放在公开面之外

1. DEBUG 与 ALLOWED_HOSTS(P0)

  • 确保生产环境 DEBUG=False。开着时,错误页面会暴露配置、环境变量和堆栈跟踪,可通过故意触发错误来提取。
  • 正确设置 ALLOWED_HOSTS,以防止在意料之外的主机名下运行。阻止详细错误对外显示。

2. SECRET_KEY(P0)

  • SECRET_KEY 是签名 Cookie、会话、CSRF 令牌以及密码重置的根基。从环境变量或密钥管理服务加载它,而非代码/仓库。
  • 泄露时及时轮换。让它远离公开目录和 DEBUG 页面(→ 不要把密钥放进公开目录)。

3. pip 依赖 CVE(P0)

  • pip-audit 或 osv-scanner 机器监控已知 CVE,以运行中的版本判定,并快速打补丁(→ 监控依赖包的 CVE · 漏洞应对实务)。
  • Django 和 Python 保持在受支持的版本,不要放着 EOL 版本不管。

4. 生产环境安全配置(P1)

Django 的大量防御是通过 SecurityMiddleware 配置的。请为生产环境设置这些:

  • SECURE_SSL_REDIRECT(强制 HTTPS)· SECURE_HSTS_SECONDS(+ INCLUDE_SUBDOMAINS/PRELOAD
  • SESSION_COOKIE_SECURE / CSRF_COOKIE_SECURE(仅 HTTPS 的 Cookie)
  • SECURE_CONTENT_TYPE_NOSNIFF
  • 运行 manage.py check --deploy 以机械地暴露这些方面的缺口。

5. 授权(P1 — 最主要的来源)

常见(危险)

  • 要求登录,但没有所有者范围
  • queryset 查了全部,没有按 ID 过滤
  • 依赖隐藏 URL / 难以猜测的 ID
  • 在某些视图上忘了权限检查

正确

  • 需要登录 + 显式的权限检查
  • 读取也做所有者范围限定(如 filter(user=request.user)
  • 每一条读取/更新/删除路径上核验
  • 授权显式构建,不交给默认值

参阅 IDOR 是什么。认证和授权是两回事;在靠近数据的地方做授权。

6. 注入与输出(P2)

  • SQL:通过 ORM 绑定。不要用 raw()/extra() 或字符串拼接构造查询(→ SQL 注入是什么)。
  • XSS:模板默认自动转义。不要把用户输入传给 mark_safe/|safe(→ XSS 是什么)。
  • 反序列化:不要加载不受信任的 pickle(可能导致代码执行)。

7. CSRF、会话、admin(P2)

  • 不要关闭默认的 CSRF 防护(→ CSRF 是什么)。
  • 限制 admin 的暴露(访问限制、更改 URL、多因素认证)。保留点击劫持防御(X-Frame-Options 默认)。
  • 给会话应用 secure/httponly/samesite,并在登录时重新生成。

8. SSRF、上传、响应头(P2)

  • 服务端取回用户提供的 URL 时,应把目标限制在允许列表,并阻断到内部 IP/元数据的访问(→ SSRF 是什么)。
  • 校验上传(类型/大小),并存放在公开面之外。
  • 安全响应头检查器 检查你自己站点的响应头。

验证:你的 Django 真的加固了吗

做完不算完——检查过才算完成。以下是针对你自己环境的防御性自查。

1

机械地检查缺口

运行 python manage.py check --deploy,确认警告都已解决。
2

生产环境不暴露 DEBUG

故意触发一个错误,确认配置/环境变量/堆栈不会对外显示。
3

授权是否有效

在测试环境里,请求别的用户的资源 ID,确认被拒绝(读取/更新/删除)。
4

密钥与依赖

确认 SECRET_KEY 不在仓库里,且 pip-audit/osv 干净。

本站的视角:开箱即用,但配置和授权仍归你自己

Django 默认守护了很多,但生产环境配置(DEBUG/SECRET_KEY/ALLOWED_HOSTS/SSL)授权是你必须按环境、按应用逐一做对的东西。我们反复看到的事故,与其说是精巧的攻击,不如说是配置/运营层面的套路:“生产环境开着 debug”“某个密钥被暴露”“压根没有授权”。所以重心在于收紧生产环境配置、让密钥保持私密、并让授权显式化。把 check --deploy 纳入你的流程,是一条捷径。

接下来读

FAQ

Q要保护 Django,第一步该做什么?
A

P0 的三件事:(1) 确保生产环境 DEBUG=False,并正确设置 ALLOWED_HOSTS;(2) 从环境加载 SECRET_KEY(不放在代码/仓库里),泄露时轮换;(3) 用机器监控 pip 依赖 CVE 并快速打补丁,以运行中的版本判定。接着再进入生产环境安全配置(SSL/HSTS/Cookie)与授权。manage.py check --deploy 能机械地暴露缺失的配置。

Q在生产环境放着 DEBUG=True 有什么危险?
A

开着 DEBUG,错误页面会显示详细内部信息——配置、环境变量、堆栈跟踪。攻击者可以故意触发错误来提取它们。在生产环境务必设置 DEBUG=False,并正确配置 ALLOWED_HOSTS。同时要阻止详细错误对外显示,并检查生产环境下的 static/media 服务方式。

Q为什么 SECRET_KEY 很重要?
A

SECRET_KEY 是签名 Cookie 和会话、CSRF 令牌以及密码重置的根基。一旦泄露,可能导致这些被伪造或篡改。不要放进代码或仓库——从环境变量或密钥管理服务加载,泄露时及时轮换。同时要防止它通过公开目录或 DEBUG 页面被暴露。

Q该检查哪些 Django 生产环境安全配置?
A

与 SecurityMiddleware 相关的那些:SECURE_SSL_REDIRECT(强制 HTTPS)、SECURE_HSTS_SECONDS(HSTS)、SESSION_COOKIE_SECURE / CSRF_COOKIE_SECURE(安全 Cookie)、SECURE_CONTENT_TYPE_NOSNIFF 等,都要按生产环境配置。运行 manage.py check --deploy 能机械地暴露这些方面的缺口。

Q如何管理 pip 依赖漏洞?
A

用 pip-audit 或 osv-scanner 机器监控已知 CVE,并以运行中的版本判定,快速打补丁。让 Django 和 Python 保持在受支持的版本,不要放着 EOL 版本不管。依赖的新鲜度,比精巧的攻击更能左右事故的成败。