Django中如何防范CSRF跨站點(diǎn)請求偽造攻擊的實(shí)現(xiàn)
CSRF概念
CSRF跨站點(diǎn)請求偽造(Cross—Site Request Forgery)。
攻擊者盜用了你的身份,以你的名義發(fā)送惡意請求,對服務(wù)器來說這個(gè)請求是完全合法的,但是卻完成了攻擊者所期望的一個(gè)操作,比如以你的名義發(fā)送郵件、發(fā)消息,盜取你的賬號,添加系統(tǒng)管理員,甚至于購買商品、虛擬貨幣轉(zhuǎn)賬等。
CSRF攻擊原理以及過程
用戶C打開瀏覽器,訪問受信任網(wǎng)站A,輸入用戶名和密碼請求登錄網(wǎng)站A;
在用戶信息通過驗(yàn)證后,網(wǎng)站A產(chǎn)生Cookie信息并返回給瀏覽器,此時(shí)用戶登錄網(wǎng)站A成功,可以正常發(fā)送請求到網(wǎng)站A;
用戶未退出網(wǎng)站A之前,在同一瀏覽器中,打開一個(gè)TAB頁訪問網(wǎng)站B;
網(wǎng)站B接收到用戶請求后,返回一些攻擊性代碼,并發(fā)出一個(gè)請求要求訪問第三方站點(diǎn)A;
瀏覽器在接收到這些攻擊性代碼后,根據(jù)網(wǎng)站B的請求,在用戶不知情的情況下攜帶Cookie信息,向網(wǎng)站A發(fā)出請求。網(wǎng)站A并不知道該請求其實(shí)是由B發(fā)起的,所以會根據(jù)用戶C的Cookie信息以C的權(quán)限處理該請求,導(dǎo)致來自網(wǎng)站B的惡意代碼被執(zhí)行。
CSRF攻擊實(shí)例
受害者 Bob 在銀行有一筆存款,通過對銀行的網(wǎng)站發(fā)送請求 http://bank.example/withdraw?account=bob&amount=1000000&for=bob2可以使 Bob 把 1000000 的存款轉(zhuǎn)到 bob2 的賬號下。通常情況下,該請求發(fā)送到網(wǎng)站后,服務(wù)器會先驗(yàn)證該請求是否來自一個(gè)合法的 session,并且該 session 的用戶 Bob 已經(jīng)成功登陸。
黑客 Mallory 自己在該銀行也有賬戶,他知道上文中的 URL 可以把錢進(jìn)行轉(zhuǎn)帳操作。Mallory 可以自己發(fā)送一個(gè)請求給銀行:http://bank.example/withdraw?account=bob&amount=1000000&for=Mallory。但是這個(gè)請求來自 Mallory 而非 Bob,他不能通過安全認(rèn)證,因此該請求不會起作用。
這時(shí),Mallory 想到使用 CSRF 的攻擊方式,他先自己做一個(gè)網(wǎng)站,在網(wǎng)站中放入如下代碼:src=”http://bank.example/withdraw?account=bob&amount=1000000&for=Mallory ”,并且通過廣告等誘使 Bob 來訪問他的網(wǎng)站。當(dāng) Bob 訪問該網(wǎng)站時(shí),上述 url 就會從 Bob 的瀏覽器發(fā)向銀行,而這個(gè)請求會附帶 Bob 瀏覽器中的 cookie 一起發(fā)向銀行服務(wù)器。大多數(shù)情況下,該請求會失敗,因?yàn)樗?Bob 的認(rèn)證信息。但是,如果 Bob 當(dāng)時(shí)恰巧剛訪問他的銀行后不久,他的瀏覽器與銀行網(wǎng)站之間的 session 尚未過期,瀏覽器的 cookie 之中含有 Bob 的認(rèn)證信息。這時(shí),悲劇發(fā)生了,這個(gè) url 請求就會得到響應(yīng),錢將從 Bob 的賬號轉(zhuǎn)移到 Mallory 的賬號,而 Bob 當(dāng)時(shí)毫不知情。等以后 Bob 發(fā)現(xiàn)賬戶錢少了,即使他去銀行查詢?nèi)罩?,他也只能發(fā)現(xiàn)確實(shí)有一個(gè)來自于他本人的合法請求轉(zhuǎn)移了資金,沒有任何被攻擊的痕跡。而 Mallory 則可以拿到錢后逍遙法外。
Django中如何防范CSRF
Django使用專門的中間件(CsrfMiddleware)來進(jìn)行CSRF防護(hù)。具體的原理如下:
1.它修改當(dāng)前處理的請求,向所有的 POST 表單增添一個(gè)隱藏的表單字段,使用名稱是 csrfmiddlewaretoken ,值為當(dāng)前會話 ID 加上一個(gè)密鑰的散列值。 如果未設(shè)置會話 ID ,該中間件將不會修改響應(yīng)結(jié)果,因此對于未使用會話的請求來說性能損失是可以忽略的。
2.對于所有含會話 cookie 集合的傳入 POST 請求,它將檢查是否存在 csrfmiddlewaretoken 及其是否正確。 如果不是的話,用戶將會收到一個(gè) 403 HTTP 錯(cuò)誤。 403 錯(cuò)誤頁面的內(nèi)容是檢測到了跨域請求偽裝。 終止請求。
該步驟確保只有源自你的站點(diǎn)的表單才能將數(shù)據(jù) POST 回來。
另外要說明的是,未使用會話 cookie 的 POST 請求無法受到保護(hù),但它們也不 需要 受到保護(hù),因?yàn)閻阂饩W(wǎng)站可用任意方法來制造這種請求。為了避免轉(zhuǎn)換非 HTML 請求,中間件在編輯響應(yīng)結(jié)果之前對它的 Content-Type 頭標(biāo)進(jìn)行檢查。 只有標(biāo)記為 text/html 或 application/xml+xhtml 的頁面才會被修改。
Django防范CSRF的具體操作
1. 將'django.middleware.csrf.CsrfViewMiddleware'添加到Django的settings.py文件中的MIDDLEWARE_CLASSES列表中(默認(rèn)已經(jīng)添加)。 該中間件必須在 SessionMiddleware 之后執(zhí)行,因此在列表中 CsrfMiddleware 必須出現(xiàn)在SessionMiddleware 之前 (因?yàn)轫憫?yīng)中間件是自后向前執(zhí)行的)。 同時(shí),它也必須在響應(yīng)被壓縮或解壓之前對響應(yīng)結(jié)果進(jìn)行處理,因此CsrfMiddleware必須在GZipMiddleware之后執(zhí)行。
MIDDLEWARE_CLASSES = ( 'django.middleware.common.CommonMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', # Uncomment the next line for simple clickjacking protection: # 'django.middleware.clickjacking.XFrameOptionsMiddleware', )
2. 在使用到POST方法提交FORM的頁面中,添加csrf_token標(biāo)簽,例如:
<form action="." method="post">{% csrf_token %}
3. 在相應(yīng)的view中,確?!癲jango.core.context_processors.csrf” 上下文處理器被正確使用,有兩種方法實(shí)現(xiàn)這一點(diǎn),一是使用RequestContext,它內(nèi)部會自動(dòng)使用到“django.core.context_processors.csrf”。另一種方法是手動(dòng)使用這個(gè)處理器,示例代碼如下:
from django.core.context_processors import csrf from django.shortcuts import render_to_response def my_view(request): c = {} c.update(csrf(request)) # ... view code here return render_to_response("a_template.html", c)
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Python實(shí)現(xiàn)使用卷積提取圖片輪廓功能示例
這篇文章主要介紹了Python實(shí)現(xiàn)使用卷積提取圖片輪廓功能,涉及Python數(shù)值運(yùn)算與圖像處理相關(guān)操作技巧,需要的朋友可以參考下2018-05-05python使用pycharm環(huán)境調(diào)用opencv庫
這篇文章主要介紹了python使用pycharm環(huán)境調(diào)用opencv庫,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-02-02Python實(shí)現(xiàn)將DOC文檔轉(zhuǎn)換為PDF的方法
這篇文章主要介紹了Python實(shí)現(xiàn)將DOC文檔轉(zhuǎn)換為PDF的方法,涉及Python調(diào)用系統(tǒng)win32com組件實(shí)現(xiàn)文件格式轉(zhuǎn)換的相關(guān)技巧,需要的朋友可以參考下2015-07-07python中not not x 與bool(x) 的區(qū)別
這篇文章主要介紹了python中not not x 與 bool(x) 的區(qū)別,我們就來做一個(gè)選擇,就是 not not x 和 bool(x) 用哪個(gè)比較好?下面一起進(jìn)入文章看看吧2021-12-12Python實(shí)現(xiàn)mysql數(shù)據(jù)庫更新表數(shù)據(jù)接口的功能
這篇文章主要給大家介紹了關(guān)于Python如何實(shí)現(xiàn)mysql數(shù)據(jù)庫更新表數(shù)據(jù)接口功能的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2017-11-11python的type?hints(類型標(biāo)注、類型注解、類型提示)示例詳解
在Python編程中,類型提示(Type Hints)是一種強(qiáng)大的工具,它能夠幫助開發(fā)者在編寫代碼時(shí)明確表達(dá)變量、函數(shù)參數(shù)和返回值的預(yù)期類型,這篇文章主要給大家介紹了關(guān)于python的type?hints(類型標(biāo)注、類型注解、類型提示)的相關(guān)資料,需要的朋友可以參考下2024-08-08pandas如何篩選某個(gè)列值是否位于某個(gè)列表內(nèi)
這篇文章主要介紹了pandas如何篩選某個(gè)列值是否位于某個(gè)列表內(nèi)問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-02-02Tensorflow使用tfrecord輸入數(shù)據(jù)格式
這篇文章主要介紹了Tensorflow使用tfrecord輸入數(shù)據(jù)格式,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-06-06