Django之CSRF


網頁向后端傳送數據的時候有兩種方式,get和post。通過設置form中的method來達到是否采用get或者是post

<form action="/show_all/" method="POST">
但是django中使用post的話會遇到如下的錯誤

這個錯誤的意思是csrf校驗失敗,request請求被丟棄掉。我們先來了解下什么是csrf。

CSRF, Cross Site Request Forgery, 跨站點偽造請求。舉例來講,某個惡意的網站上有一個指向你的網站的鏈接,如果某個用戶已經登錄到你的網站上了,那么當這個用戶點擊這個惡意網站上的那個鏈接時,就會向你的網站發來一個請求,你的網站會以為這個請求是用戶自己發來的,其實呢,這個請求是那個惡意網站偽造

舉個例子:

假如用戶abc登錄了銀行的網站,並且向abc2進行了轉賬,對銀行發送的請求是 http://bank.example/withdraw?account=abc&amount=1000000&for=abc2. 通常情況下,請求發送到服務器后,服務器會首先驗證是否是合法的session,如果是則轉賬成功。假設黑客也有同樣銀行的賬號。他知道轉賬的時候會生成如上的請求鏈接。黑客也可以發送同樣的請求給服務器要求轉賬給自己。但是服務器校驗他的這個請求不是合法的session。因此黑客想到了CSRF的方式。他自己做一個網站,在網站中發下如下鏈接:http://bank.example/withdraw?account=abc&amount=1000000&for=heike 並且通過廣告或其他的方式誘使abc點擊這個鏈接,上述 url 就會從 abc的瀏覽器發向銀行,而這個請求會附帶 abc瀏覽器中的 cookie 一起發向銀行服務器。大多數情況下,該請求會失敗,因為他要求 abc 的認證信息。但是,如果 abc 當時恰巧剛訪問他的銀行后不久,他的瀏覽器與銀行網站之間的 session 尚未過期,瀏覽器的 cookie 之中含有 abc 的認證信息。這時,悲劇發生了,這個 url 請求就會得到響應,錢將從 abc 的賬號轉移到黑客的賬號,而 abc 當時毫不知情

那么解決辦法是什么呢:

CSRF 攻擊之所以能夠成功,是因為黑客可以完全偽造用戶的請求,該請求中所有的用戶驗證信息都是存在於 cookie 中,因此黑客可以在不知道這些驗證信息的情況下直接利用用戶自己的 cookie 來通過安全驗證。要抵御 CSRF,關鍵在於在請求中放入黑客所不能偽造的信息,並且該信息不存在於 cookie 之中。可以在 HTTP 請求中以參數的形式加入一個隨機產生的 token,並在服務器端建立一個攔截器來驗證這個 token,如果請求中沒有 token 或者 token 內容不正確,則認為可能是 CSRF 攻擊而拒絕該請求。

那么回到django中的post失敗有兩種解決辦法:

解決辦法一:將csrf中間層注釋掉

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
#    'django.middleware.csrf.CsrfViewMiddleware',
   
'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
此時將不會進行csrf的校驗,但如前面所述,這是一種不安全的行為。而且djano也不推薦使用
 
解決辦法二:
在前面的提示中有這樣一句話:

In any template that uses a POST form, use the csrf_token tag inside the <form> element if the form is for an internal URL, e.g.:

<form action="" method="post">{% csrf_token %}

也就是說在網頁中加入csrf_token的標簽就可以通過csrf校驗
Django 提供的 CSRF 防護機制:
1 django 第一次響應來自某個客戶端的請求時,會在服務器端隨機生成一個 token,把這個 token 放在 cookie 里。然后每次 POST 請求都會帶上這個 token,這樣就能避免被 CSRF 攻擊。
2 在返回的 HTTP 響應的 cookie 里,django 會為你添加一個 csrftoken 字段,其值為一個自動生成的 token,在所有的 POST 表單時,必須包含一個 csrfmiddlewaretoken 字段 (只需要在模板里加一個 tag, django 就會自動幫你生成,見下面)
3 在處理 POST 請求之前,django 會驗證這個請求的 cookie 里的 csrftoken 字段的值和提交的表單里的 csrfmiddlewaretoken 字段的值是否一樣。如果一樣,則表明這是一個合法的請求,否則,這個請求可能是來自於別人的 csrf 攻擊,返回 403 Forbidden.
4 在所有 ajax POST 請求里,添加一個 X-CSRFTOKEN header,其值為 cookie 里的 csrftoken 的值
 
       


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM