這份文檔是 Django 的安全功能的概述。 它包括給 Django 驅(qū)動的網(wǎng)站一些加固建議。
XSS攻擊允許用戶注入客戶端腳本到其他用戶的瀏覽器里。 這通常是通過存儲在數(shù)據(jù)庫中的惡意腳本,它將檢索并顯示給其他用戶,或者通過讓用戶點擊一個鏈接,這將導致攻擊者的 JavaScript 被用戶的瀏覽器執(zhí)行。 然而,XSS 攻擊可以來自任何不受信任的源數(shù)據(jù),如 Cookie 或 Web 服務,任何沒有經(jīng)過充分處理就包含在網(wǎng)頁中的數(shù)據(jù)。
使用 Django 模板保護你免受多數(shù) XSS 攻擊。 然而,重要的是要了解它提供了什么保護及其局限性。
Django 模板會 編碼特殊字符 ,這些字符在 HTML 中都是特別危險的。 雖然這可以防止大多數(shù)惡意輸入的用戶,但它不能完全保證萬無一失。 例如,它不會防護以下內(nèi)容:
<style class=>...</style>
如果 var 設置為 'class1 onmouseover=javascript:func()', 這可能會導致在未經(jīng)授權(quán)的 JavaScript 的執(zhí)行,取決于瀏覽器如何呈現(xiàn)不完整的 HTML。 (對屬性值使用引號可以修復這種情況。)
同樣重要的是is_safe要特別小心的用在 自定義模板標簽,safe 模板標簽,mark_safe ,還有 autoescape 被關閉的時候。
此外,如果您使用的是模板系統(tǒng)輸出 HTML 以外的東西,可能會有完全不同的字符和單詞需要編碼。
你也應該在數(shù)據(jù)庫中存儲 HTML 的時候要非常小心,尤其是當 HTML 被檢索然后展示出來。
CSRF 攻擊允許惡意用戶在另一個用戶不知情或者未同意的情況下,以他的身份執(zhí)行操作。
Django 對大多數(shù)類型的 CSRF 攻擊有內(nèi)置的保護,在適當情況下你可以開啟并使用它 。 然而,對于任何解決技術(shù),都有它的局限性。 例如,CSRF 模塊可以在全局范圍內(nèi)或為特定視圖被禁用 。 您應該只在您知道在做什么的情況下操作。 還有其他 限制 如果你的網(wǎng)站有子域名并且在你的控制之外。
CSRF 防護 是通過檢查每個 POST 請求的一個隨機數(shù)(nonce)來工作。 這確保了惡意用戶不能簡單“回放”你網(wǎng)站上面表單的POST,以及讓另一個登錄的用戶無意中提交表單。惡意用戶必須知道這個隨機數(shù),它是用戶特定的(存在cookie里)。
使用 HTTPS來部署的時候,CsrfViewMiddleware會檢查HTTP referer協(xié)議頭是否設置為同源的URL(包括子域和端口)。因為HTTPS提供了附加的安全保護,轉(zhuǎn)發(fā)不安全的連接請求時,必須確保鏈接使用 HTTPS,并使用HSTS支持的瀏覽器。
使用csrf_exempt裝飾器來標記視圖時,要非常小心,除非這是極其必要的。
SQl注入是一種攻擊類型,惡意用戶可以在系統(tǒng)數(shù)據(jù)庫中執(zhí)行任意SQL代碼。這可能會導致記錄刪除或者數(shù)據(jù)泄露。
通過使用Django的查詢集,產(chǎn)生的SQL會由底層數(shù)據(jù)庫驅(qū)動正確地轉(zhuǎn)義。然而,Django也允許開發(fā)者編寫原始查詢或者執(zhí)行自定義sql。這些功能應該謹慎使用,并且你應該時刻小心正確轉(zhuǎn)義任何用戶可以控制的參數(shù)。另外,你在使用extra()的時候應該謹慎行事。
點擊劫持是一類攻擊,惡意站點在一個frame中包裹了另一個站點。這類攻擊可能導致用戶被誘導在目標站點做出一些無意識的行為。
Django在X-Frame-Options 中間件的表單中中含有 點擊劫持保護 ,它在支持的瀏覽器中可以保護站點免于在frame中渲染。也可以在每個視圖中禁止這一保護,或者配置要發(fā)送的額外的協(xié)議頭。
對于任何不需要將頁面包裝在三方站點的frame中,或者只需要包含它的一部分的站點,都強烈推薦啟用這一中間件。
把你的站點部署在HTTPS下總是更安全的,盡管在所有情況下不都有效。如果不這樣,惡意的網(wǎng)絡用戶可能會嗅探授權(quán)證書,或者其他在客戶端和服務端之間傳輸?shù)男畔?,或者一些情況下 -- 活躍的網(wǎng)絡攻擊者 -- 會修改在兩邊傳輸?shù)臄?shù)據(jù)。
如果你想要使用HTTPS提供的保護,并且在你的服務器上開啟它,你需要遵循一些額外的步驟:
如果必要的話,設置 SECURE_PROXY_SSL_HEADER,確保你已經(jīng)徹底了解警告。未能實現(xiàn)它會導致CSRF方面的缺陷,也是很危險的!
設置重定向,以便HTTP下的請求可以重定向到HTTPS。
這可以通過自定義的中間件來實現(xiàn)。請注意SECURE_PROXY_SSL_HEADER下的警告。對于反向代理的情況,配置web主服務器來重定向到HTTPS或許是最簡單也許是最安全的做法。
使用“安全的”cookie。
如果瀏覽器的連接一開始通過HTTP,這是大多數(shù)瀏覽器的通常情況,已存在的cookie可能會被泄露。因此,你應該將SESSION_COOKIE_SECURE 和CSRF_COOKIE_SECURE設置為True。這會使瀏覽器只在HTTPS連接中發(fā)送這些cookie。要注意這意味著會話在HTTP下不能工作,并且CSRF保護功能會在HTTP下阻止接受任何POST數(shù)據(jù)(如果你把所有HTTP請求都重定向到HTTPS之后就沒問題了)。
使用 HTTP 強制安全傳輸 (HSTS)
HSTS 是一個HTTP協(xié)議頭,它通知瀏覽器,到特定站點的所有鏈接都一直使用HTTPS。通過和重定向HTTP請求到HTTPS一起使用,確保連接總是享有附加的SSL安全保障,由一個已存在的成功的連接提供。HSTS通常在web服務器上面配置。
在某些情況下,Django使用客戶端提供的Host 協(xié)議頭來構(gòu)造URL。雖然這些值可以被審查,來防止跨站腳本攻擊(XSS),但是一個假的Host值可以用于跨站請求偽造(CSRF),有害的緩存攻擊,以及email中的有害鏈接。
Because even seemingly-secure web server configurations are susceptible to fake Host headers, Django validates Host headers against the ALLOWED_HOSTS setting in the django.http.HttpRequest.get_host() method.
驗證只通過get_host()來應用;如果你的代碼從request.META中直接訪問Host協(xié)議頭,就會繞開這一安全防護。
詳見完整的ALLOWED_HOSTS文檔。
Warning
Previous versions of this document recommended configuring your web server to ensure it validates incoming HTTP Host headers. While this is still recommended, in many common web servers a configuration that seems to validate the Host header may not in fact do so. For instance, even if Apache is configured such that your Django site is served from a non-default virtual host with the ServerName set, it is still possible for an HTTP request to match this virtual host and supply a fake Host header. Thus, Django now requires that you set ALLOWED_HOSTS explicitly rather than relying on web server configuration.
另外,就像1.3.1,如果你的配置需要它的話,Django 需要你顯式開啟對X-Forwarded-Host 協(xié)議頭的支持(通過 USE_X_FORWARDED_HOST 這只)。
類似于部署在站點上的CSRF 限制 使不受信任的用戶不能訪問任何子域,django.contrib.sessions也有一些限制。詳見安全中會話的話題指南。
注意
考慮在云服務器或CDN上面部署靜態(tài)文件來避免一些此類問題。
如果你的站點接受上傳文件,強烈推薦你在web服務器配置中,將這些上傳限制為合理的大小,來避免拒絕服務(DOS)攻擊。在Apache中,這可以簡單地使用LimitRequestBody指令。
如果你自己處理靜態(tài)文件,確保像Apache的mod_php的處理器已關閉,它會將靜態(tài)文件執(zhí)行為代碼。你并不希望用戶能夠通過上傳和請求一個精心構(gòu)造的文件來執(zhí)行任意代碼。
Django’s media upload handling poses some vulnerabilities when that media is served in ways that do not follow security best practices. Specifically, an HTML file can be uploaded as an image if that file contains a valid PNG header followed by malicious HTML. This file will pass verification of the library that Django uses for ImageField image processing (Pillow). When this file is subsequently displayed to a user, it may be displayed as HTML depending on the type and configuration of your web server.
No bulletproof technical solution exists at the framework level to safely validate all user uploaded file content, however, there are some other steps you can take to mitigate these attacks:
example.com, you would want to serve uploaded content (the MEDIA_URL setting) from something like usercontent-example.com. It’s not sufficient to serve content from a subdomain like usercontent.example.com.
雖然Django提供了開箱即用的,良好的安全保護,但是合理地部署你的應用,以及利用web服務器、操作系統(tǒng)和其他組件的安全保護仍然很重要。
SECRET_KEY。譯者:Django 文檔協(xié)作翻譯小組,原文:Security overview。
本文以 CC BY-NC-SA 3.0 協(xié)議發(fā)布,轉(zhuǎn)載請保留作者署名和文章出處。
Django 文檔協(xié)作翻譯小組人手緊缺,有興趣的朋友可以加入我們,完全公益性質(zhì)。交流群:467338606。