這份文檔是 Django 的安全功能的概述。 它包括給 Django 驅(qū)動(dòng)的網(wǎng)站一些加固建議。
XSS攻擊允許用戶注入客戶端腳本到其他用戶的瀏覽器里。 這通常是通過(guò)存儲(chǔ)在數(shù)據(jù)庫(kù)中的惡意腳本,它將檢索并顯示給其他用戶,或者通過(guò)讓用戶點(diǎn)擊一個(gè)鏈接,這將導(dǎo)致攻擊者的 JavaScript 被用戶的瀏覽器執(zhí)行。 然而,XSS 攻擊可以來(lái)自任何不受信任的源數(shù)據(jù),如 Cookie 或 Web 服務(wù),任何沒(méi)有經(jīng)過(guò)充分處理就包含在網(wǎng)頁(yè)中的數(shù)據(jù)。
使用 Django 模板保護(hù)你免受多數(shù) XSS 攻擊。 然而,重要的是要了解它提供了什么保護(hù)及其局限性。
Django 模板會(huì) 編碼特殊字符 ,這些字符在 HTML 中都是特別危險(xiǎn)的。 雖然這可以防止大多數(shù)惡意輸入的用戶,但它不能完全保證萬(wàn)無(wú)一失。 例如,它不會(huì)防護(hù)以下內(nèi)容:
<style class=>...</style>
如果 var 設(shè)置為 'class1 onmouseover=javascript:func()', 這可能會(huì)導(dǎo)致在未經(jīng)授權(quán)的 JavaScript 的執(zhí)行,取決于瀏覽器如何呈現(xiàn)不完整的 HTML。 (對(duì)屬性值使用引號(hào)可以修復(fù)這種情況。)
同樣重要的是is_safe要特別小心的用在 自定義模板標(biāo)簽,safe 模板標(biāo)簽,mark_safe ,還有 autoescape 被關(guān)閉的時(shí)候。
此外,如果您使用的是模板系統(tǒng)輸出 HTML 以外的東西,可能會(huì)有完全不同的字符和單詞需要編碼。
你也應(yīng)該在數(shù)據(jù)庫(kù)中存儲(chǔ) HTML 的時(shí)候要非常小心,尤其是當(dāng) HTML 被檢索然后展示出來(lái)。
CSRF 攻擊允許惡意用戶在另一個(gè)用戶不知情或者未同意的情況下,以他的身份執(zhí)行操作。
Django 對(duì)大多數(shù)類型的 CSRF 攻擊有內(nèi)置的保護(hù),在適當(dāng)情況下你可以開(kāi)啟并使用它 。 然而,對(duì)于任何解決技術(shù),都有它的局限性。 例如,CSRF 模塊可以在全局范圍內(nèi)或?yàn)樘囟ㄒ晥D被禁用 。 您應(yīng)該只在您知道在做什么的情況下操作。 還有其他 限制 如果你的網(wǎng)站有子域名并且在你的控制之外。
CSRF 防護(hù) 是通過(guò)檢查每個(gè) POST 請(qǐng)求的一個(gè)隨機(jī)數(shù)(nonce)來(lái)工作。 這確保了惡意用戶不能簡(jiǎn)單“回放”你網(wǎng)站上面表單的POST,以及讓另一個(gè)登錄的用戶無(wú)意中提交表單。惡意用戶必須知道這個(gè)隨機(jī)數(shù),它是用戶特定的(存在cookie里)。
使用 HTTPS來(lái)部署的時(shí)候,CsrfViewMiddleware會(huì)檢查HTTP referer協(xié)議頭是否設(shè)置為同源的URL(包括子域和端口)。因?yàn)镠TTPS提供了附加的安全保護(hù),轉(zhuǎn)發(fā)不安全的連接請(qǐng)求時(shí),必須確保鏈接使用 HTTPS,并使用HSTS支持的瀏覽器。
使用csrf_exempt裝飾器來(lái)標(biāo)記視圖時(shí),要非常小心,除非這是極其必要的。
SQl注入是一種攻擊類型,惡意用戶可以在系統(tǒng)數(shù)據(jù)庫(kù)中執(zhí)行任意SQL代碼。這可能會(huì)導(dǎo)致記錄刪除或者數(shù)據(jù)泄露。
通過(guò)使用Django的查詢集,產(chǎn)生的SQL會(huì)由底層數(shù)據(jù)庫(kù)驅(qū)動(dòng)正確地轉(zhuǎn)義。然而,Django也允許開(kāi)發(fā)者編寫(xiě)原始查詢或者執(zhí)行自定義sql。這些功能應(yīng)該謹(jǐn)慎使用,并且你應(yīng)該時(shí)刻小心正確轉(zhuǎn)義任何用戶可以控制的參數(shù)。另外,你在使用extra()的時(shí)候應(yīng)該謹(jǐn)慎行事。
點(diǎn)擊劫持是一類攻擊,惡意站點(diǎn)在一個(gè)frame中包裹了另一個(gè)站點(diǎn)。這類攻擊可能導(dǎo)致用戶被誘導(dǎo)在目標(biāo)站點(diǎn)做出一些無(wú)意識(shí)的行為。
Django在X-Frame-Options 中間件的表單中中含有 點(diǎn)擊劫持保護(hù) ,它在支持的瀏覽器中可以保護(hù)站點(diǎn)免于在frame中渲染。也可以在每個(gè)視圖中禁止這一保護(hù),或者配置要發(fā)送的額外的協(xié)議頭。
對(duì)于任何不需要將頁(yè)面包裝在三方站點(diǎn)的frame中,或者只需要包含它的一部分的站點(diǎn),都強(qiáng)烈推薦啟用這一中間件。
把你的站點(diǎn)部署在HTTPS下總是更安全的,盡管在所有情況下不都有效。如果不這樣,惡意的網(wǎng)絡(luò)用戶可能會(huì)嗅探授權(quán)證書(shū),或者其他在客戶端和服務(wù)端之間傳輸?shù)男畔ⅲ蛘咭恍┣闆r下 -- 活躍的網(wǎng)絡(luò)攻擊者 -- 會(huì)修改在兩邊傳輸?shù)臄?shù)據(jù)。
如果你想要使用HTTPS提供的保護(hù),并且在你的服務(wù)器上開(kāi)啟它,你需要遵循一些額外的步驟:
如果必要的話,設(shè)置 SECURE_PROXY_SSL_HEADER,確保你已經(jīng)徹底了解警告。未能實(shí)現(xiàn)它會(huì)導(dǎo)致CSRF方面的缺陷,也是很危險(xiǎn)的!
設(shè)置重定向,以便HTTP下的請(qǐng)求可以重定向到HTTPS。
這可以通過(guò)自定義的中間件來(lái)實(shí)現(xiàn)。請(qǐng)注意SECURE_PROXY_SSL_HEADER下的警告。對(duì)于反向代理的情況,配置web主服務(wù)器來(lái)重定向到HTTPS或許是最簡(jiǎn)單也許是最安全的做法。
使用“安全的”cookie。
如果瀏覽器的連接一開(kāi)始通過(guò)HTTP,這是大多數(shù)瀏覽器的通常情況,已存在的cookie可能會(huì)被泄露。因此,你應(yīng)該將SESSION_COOKIE_SECURE 和CSRF_COOKIE_SECURE設(shè)置為True。這會(huì)使瀏覽器只在HTTPS連接中發(fā)送這些cookie。要注意這意味著會(huì)話在HTTP下不能工作,并且CSRF保護(hù)功能會(huì)在HTTP下阻止接受任何POST數(shù)據(jù)(如果你把所有HTTP請(qǐng)求都重定向到HTTPS之后就沒(méi)問(wèn)題了)。
使用 HTTP 強(qiáng)制安全傳輸 (HSTS)
HSTS 是一個(gè)HTTP協(xié)議頭,它通知瀏覽器,到特定站點(diǎn)的所有鏈接都一直使用HTTPS。通過(guò)和重定向HTTP請(qǐng)求到HTTPS一起使用,確保連接總是享有附加的SSL安全保障,由一個(gè)已存在的成功的連接提供。HSTS通常在web服務(wù)器上面配置。
在某些情況下,Django使用客戶端提供的Host 協(xié)議頭來(lái)構(gòu)造URL。雖然這些值可以被審查,來(lái)防止跨站腳本攻擊(XSS),但是一個(gè)假的Host值可以用于跨站請(qǐng)求偽造(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.
驗(yàn)證只通過(guò)get_host()來(lái)應(yīng)用;如果你的代碼從request.META中直接訪問(wèn)Host協(xié)議頭,就會(huì)繞開(kāi)這一安全防護(hù)。
詳見(jiàn)完整的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 需要你顯式開(kāi)啟對(duì)X-Forwarded-Host 協(xié)議頭的支持(通過(guò) USE_X_FORWARDED_HOST 這只)。
類似于部署在站點(diǎn)上的CSRF 限制 使不受信任的用戶不能訪問(wèn)任何子域,django.contrib.sessions也有一些限制。詳見(jiàn)安全中會(huì)話的話題指南。
注意
考慮在云服務(wù)器或CDN上面部署靜態(tài)文件來(lái)避免一些此類問(wèn)題。
如果你的站點(diǎn)接受上傳文件,強(qiáng)烈推薦你在web服務(wù)器配置中,將這些上傳限制為合理的大小,來(lái)避免拒絕服務(wù)(DOS)攻擊。在Apache中,這可以簡(jiǎn)單地使用LimitRequestBody指令。
如果你自己處理靜態(tài)文件,確保像Apache的mod_php的處理器已關(guān)閉,它會(huì)將靜態(tài)文件執(zhí)行為代碼。你并不希望用戶能夠通過(guò)上傳和請(qǐng)求一個(gè)精心構(gòu)造的文件來(lái)執(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提供了開(kāi)箱即用的,良好的安全保護(hù),但是合理地部署你的應(yīng)用,以及利用web服務(wù)器、操作系統(tǒng)和其他組件的安全保護(hù)仍然很重要。
SECRET_KEY。譯者:Django 文檔協(xié)作翻譯小組,原文:Security overview。
本文以 CC BY-NC-SA 3.0 協(xié)議發(fā)布,轉(zhuǎn)載請(qǐng)保留作者署名和文章出處。
Django 文檔協(xié)作翻譯小組人手緊缺,有興趣的朋友可以加入我們,完全公益性質(zhì)。交流群:467338606。