1. 程式人生 > >Django 的 CSRF 保護機制

Django 的 CSRF 保護機制

ken 渲染 _for ID 一個 RF oss RM ext

用 django 有多久,我跟 csrf 這個概念打交道就有久了。

  • 每次初始化一個項目時都能看到 django.middleware.csrf.CsrfViewMiddleware 這個中間件
  • 每次在模板裏寫 form 時都知道要加一個 {% csrf_token %} tag
  • 每次發 ajax POST 請求,都需要加一個 X_CSRFTOKEN 的 header

但是一直我都是知其然而不知其所以然,沒有把 csrf 的機制弄清楚。昨天稍微研究了一下,總結如下。

什麽是 CSRF

CSRF, Cross Site Request Forgery, 跨站點偽造請求。舉例來講,某個惡意的網站上有一個指向你的網站的鏈接,如果

某個用戶已經登錄到你的網站上了,那麽當這個用戶點擊這個惡意網站上的那個鏈接時,就會向你的網站發來一個請求,

你的網站會以為這個請求是用戶自己發來的,其實呢,這個請求是那個惡意網站偽造的。

具體的細節及其危害見 wikipedia

Django 提供的 CSRF 防護機制

django 第一次響應來自某個客戶端的請求時,會在服務器端隨機生成一個 token,把這個 token 放在 cookie 裏。然後每次 POST 請求都會帶上這個 token,

這樣就能避免被 CSRF 攻擊。

  1. 在返回的 HTTP 響應的 cookie 裏,django 會為你添加一個 csrftoken 字段,其值為一個自動生成的 token
  2. 在所有的 POST 表單時,必須包含一個 csrfmiddlewaretoken 字段 (只需要在模板裏加一個 tag, django 就會自動幫你生成,見下面)
  3. 在處理 POST 請求之前,django 會驗證這個請求的 cookie 裏的 csrftoken 字段的值和提交的表單裏的 csrfmiddlewaretoken 字段的值是否一樣。如果一樣,則表明這是一個合法的請求,否則,這個請求可能是來自於別人的 csrf 攻擊,返回 403 Forbidden.
  4. 在所有 ajax POST 請求裏,添加一個 X-CSRFTOKEN header,其值為 cookie 裏的 csrftoken 的值

Django 裏如何使用 CSRF 防護

  • 首先,最基本的原則是:GET 請求不要用有副作用。也就是說任何處理 GET 請求的代碼對資源的訪問都一定要是“只讀“的。
  • 要啟用 django.middleware.csrf.CsrfViewMiddleware 這個中間件
  • 再次,在所有的 POST 表單元素時,需要加上一個 {% csrf_token %} tag
  • 在渲染模塊時,使用 RequestContext。RequestContext 會處理 csrf_token 這個 tag, 從而自動為表單添加一個名為 csrfmiddlewaretoken 的 input

方法一:

在發送post請求的html頁面前加入{% csrf_token %}

方法二:

在處理post數據的view前加@csrf_exempt裝飾符

@csrf_exempt  
def profile_delte(request):   
  del_file=request.POST.get("delete_file",‘‘)  

Django 的 CSRF 保護機制