Django 的 CSRF 保護機制


用 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


免責聲明!

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



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