跳至主要內容
>_ITDITD網站資安平台

各框架對策

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從環境載入,不寫在程式碼/repo。外洩時輪替
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 token 與密碼重設的基礎。從環境變數或秘密管理載入,別寫在程式碼/repo。
  • 外洩就立即輪替。避免它經由公開目錄與 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
  • 有些 view 忘了做權限檢查

正確

  • 需登入+明確的權限檢查
  • 連讀取也限定為擁有者範圍(例如 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 不在 repo 裡,且 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(不寫在程式碼/repo 裡)並在外洩時輪替;(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 token、密碼重設的基礎。外洩可能導致偽造或竄改這些內容。別把它放在程式碼或 repo 裡——從環境變數或秘密管理載入,並在外洩時立即輪替。也要避免它經由公開目錄或 DEBUG 頁面外露。

QDjango 的正式環境安全設定該檢查哪些項目?
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 會以機器方式揪出這些的缺口。

Qpip 相依套件的漏洞要如何管理?
A

用 pip-audit 或 osv-scanner 以機器監控已知 CVE 並迅速修補,以實際執行的版本判定。把 Django 與 Python 保持在受支援的版本,別放任 EOL 版本。相依套件的新鮮度,比起精巧的攻擊,是更貼近現實的事故分水嶺。