什么是CSRF
下面這張圖片說明了CSRF的攻擊原理:
Django中如何防范CSRF
Django使用專門的中間件(CsrfMiddleware)來進行CSRF防護。具體的原理如下:
1.它修改當前處理的請求,向所有的 POST 表單增添一個隱藏的表單字段,使用名稱是 csrfmiddlewaretoken ,值為當前會話 ID 加上一個密鑰的散列值。 如果未設置會話 ID ,該中間件將不會修改響應結果,因此對於未使用會話的請求來說性能損失是可以忽略的。
2.對於所有含會話 cookie 集合的傳入 POST 請求,它將檢查是否存在 csrfmiddlewaretoken 及其是否正確。 如果不是的話,用戶將會收到一個 403 HTTP 錯誤。 403 錯誤頁面的內容是檢測到了跨域請求偽裝。 終止請求。
該步驟確保只有源自你的站點的表單才能將數據 POST 回來。
另外要說明的是,未使用會話 cookie 的 POST 請求無法受到保護,但它們也不 需要 受到保護,因為惡意網站可用任意方法來制造這種請求。為了避免轉換非 HTML 請求,中間件在編輯響應結果之前對它的 Content-Type 頭標進行檢查。 只有標記為 text/html 或 application/xml+xhtml 的頁面才會被修改。
Django防范CSRF的具體操作
1.將'django.middleware.csrf.CsrfViewMiddleware'添加到Django的settings.py文件中的MIDDLEWARE_CLASSES列表中(默認已經添加)。 該中間件必須在 SessionMiddleware 之后執行,因此在列表中 CsrfMiddleware 必須出現在SessionMiddleware 之前 (因為響應中間件是自后向前執行的)。 同時,它也必須在響應被壓縮或解壓之前對響應結果進行處理,因此CsrfMiddleware必須在GZipMiddleware之后執行。
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標簽,例如:
<form action="." method="post">{% csrf_token %}
3.在相應的view中,確保“django.core.context_processors.csrf” 上下文處理器被正確使用,有兩種方法實現這一點,一是使用RequestContext,它內部會自動使用到“django.core.context_processors.csrf”。另一種方法是手動使用這個處理器,示例代碼如下:
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)