各框架對策
Django 的資安對策 — 正式環境強化實務參考
Django 的正式環境強化參考:優先度清單,加上 DEBUG/ALLOWED_HOSTS、SECRET_KEY、pip CVE、正式環境安全設定、授權、注入與 SSRF。以防禦視角撰寫,不含攻擊步驟。
對象:正在維運 Django 應用程式的人。這裡不談攻擊步驟——這是用來強化的可實作參考:依優先度排序的清單、各領域指引與自我檢查。想看跨框架的全貌,請參閱 各框架資安對策的入口。
依優先度排序的強化清單
由上往下逐項處理這張表。P0 是前提,P1 是最頻繁的事故來源,P2 是持續性的維運衛生。
P0 ── 前提(先做這個)
DEBUG=False+ALLOWED_HOSTS/把 SECRET_KEY 外部化/迅速修補 pip 相依套件 CVE
P1 ── 最主要的事故來源
正式環境安全設定(SSL/HSTS/cookie)/授權(擁有者範圍)
P2 ── 維運衛生
注入與輸出/CSRF、工作階段、admin/SSRF、上傳
| 優先度 | 對策 | 具體(Django) |
|---|---|---|
| P0 | DEBUG/ALLOWED_HOSTS | 正式環境 DEBUG=False+設好 ALLOWED_HOSTS。別外露詳細錯誤 |
| P0 | SECRET_KEY | 從環境載入,不寫在程式碼/repo。外洩時輪替 |
| P0 | pip 相依套件 CVE | 以 pip-audit / osv-scanner 監控;以實際執行版本判定,迅速修補 |
| P1 | 正式環境安全設定 | SECURE_SSL_REDIRECT、SECURE_HSTS_SECONDS、SESSION_COOKIE_SECURE、CSRF_COOKIE_SECURE、SECURE_CONTENT_TYPE_NOSNIFF |
| P1 | 明確的授權 | 需登入+權限+以 filter(user=request.user) 做擁有者範圍 |
| P2 | 注入/輸出 | 透過 ORM 綁定。避免 raw()/extra() 串接。別把輸入交給 mark_safe/` |
| P2 | CSRF/工作階段/admin | 別停用 CSRF(預設)。限制 admin 的暴露 |
| P2 | SSRF/上傳 | 伺服器端取得採允許清單+阻擋內部 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 真的強化了嗎?
做完不是終點——檢查過才算完成。以下是針對你自己環境的防禦性自我檢查。
以機器方式檢查缺口
python manage.py check --deploy,確認警告都已解決。正式環境不外露 DEBUG
授權有效
秘密與相依套件
SECRET_KEY 不在 repo 裡,且 pip-audit/osv 為乾淨。本站的觀點:電池全含,但設定與授權在你身上
Django 預設守住了很多,但正式環境設定(DEBUG/SECRET_KEY/ALLOWED_HOSTS/SSL)與授權,是你必須依環境、依應用程式各自做對的事。我們反覆看到的事故,與其說是精巧的攻擊,不如說是設定/維運的型態:「正式環境的 debug 開著」「秘密外露了」「根本沒有授權」。所以防禦的重心是收緊正式環境設定、把秘密保持私密、把授權寫明確。把 check --deploy 納入你的流程是捷徑。
接下來讀
- 入口:各框架資安對策 · Laravel 資安對策(相近的正式環境 DEBUG/秘密外露)
- 實務:漏洞應變實務手冊 · 監控相依套件的 CVE · 別把秘密放在公開目錄
- 名詞:IDOR 是什麼 · SQL 注入 · XSS · CSRF · SSRF
- 工具:安全標頭檢測
FAQ
Q要保護 Django,第一步該做什麼?
三個 P0 項目:(1) 在正式環境確保 DEBUG=False 並正確設定 ALLOWED_HOSTS;(2) 從環境載入 SECRET_KEY(不寫在程式碼/repo 裡)並在外洩時輪替;(3) 用機器監控 pip 相依套件的 CVE 並迅速修補,以實際執行的版本判定。接著再進到正式環境安全設定(SSL/HSTS/cookie)與授權。manage.py check --deploy 會以機器方式揪出遺漏的設定。
Q在正式環境放任 DEBUG=True 有什麼危險?
DEBUG 開著時,錯誤頁面可能顯示詳細的內部資訊——設定值、環境變數、堆疊追蹤。攻擊者可以故意觸發錯誤來抽取這些。在正式環境務必設 DEBUG=False,並正確設定 ALLOWED_HOSTS。同時也要停止詳細錯誤對外顯示,並檢視 static/media 的正式環境配送方式。
Q為什麼 SECRET_KEY 很重要?
SECRET_KEY 是簽章 cookie 與工作階段、CSRF token、密碼重設的基礎。外洩可能導致偽造或竄改這些內容。別把它放在程式碼或 repo 裡——從環境變數或秘密管理載入,並在外洩時立即輪替。也要避免它經由公開目錄或 DEBUG 頁面外露。
QDjango 的正式環境安全設定該檢查哪些項目?
與 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 相依套件的漏洞要如何管理?
用 pip-audit 或 osv-scanner 以機器監控已知 CVE 並迅速修補,以實際執行的版本判定。把 Django 與 Python 保持在受支援的版本,別放任 EOL 版本。相依套件的新鮮度,比起精巧的攻擊,是更貼近現實的事故分水嶺。