django csrf工作原理
參考連結地址:https://yiyibooks.cn/xx/Django_1.11.6/ref/csrf.html
-
一個基於隨機secret值的CSRF cookie,其它站點無法獲取到。
此Cookie由
CsrfViewMiddleware
設定。 它和每個響應一起傳送,如果請求上沒有設定,則呼叫django.middleware.csrf.get_token()
(這個函式用於內部獲取CSRF token)。為了防止BREACH攻擊,token不僅僅是secret;一個隨機的salt被新增到secret中,並用來加擾它。
出於安全考慮,每當使用者登入時,secret的值都會更改。
-
所有傳出POST表單中都有一個名為“csrfmiddlewaretoken”的隱藏表單欄位。 該欄位的值還是這個secret的值,其中添加了salt並且用於加擾它。 在每次呼叫
get_token()
時重新生成salt,所以在每個響應中這個表單欄位值都會改變。此部分由模板標記完成。
-
對於所有未使用HTTP GET,HEAD,OPTIONS或TRACE的傳入請求,必須存在CSRF cookie,並且“csrfmiddlewaretoken”欄位必須存在且正確。 如果不是,使用者將得到403錯誤。
當驗證'csrfmiddlewaretoken'欄位值時,只將secret而不是完整的token與cookie值中的secret進行比較
此檢查由
CsrfViewMiddleware
完成。 -
此外,對於HTTPS請求,
CsrfViewMiddleware
會執行嚴格的referer檢查。 這意味著即使子域可以設定或修改域上的Cookie,也不能強制使用者POST給你的應用,因為該請求不是來自精確的域。這也解決了在使用會話獨立機密時在HTTPS下可能發生的中間人攻擊,由於客戶端接受HTTP
Set-Cookie
頭(事實上),即使他們正在與HTTPS下的站點通話。 (由於HTTP中存在的Referer
如果設定了
CSRF_COOKIE_DOMAIN
設定,則會將referer與之進行比較。 這個設定支援子域。 例如,CSRF_COOKIE_DOMAIN = '.example.com'
將允許來自www.example.com
和api.example.com
的POST請求。 如果這個設定未設定,則referer必須匹配HTTP的Host
頭部。可以使用
CSRF_TRUSTED_ORIGINS
設定擴充套件接受的引薦者超出當前主機或Cookie域。
這樣可以確保只有源自可信域的表單才能用於POST資料。
它故意忽略GET請求(以及由 RFC 7231定義為“安全”的其他請求)。 這些請求不應該有任何潛在的危險副作用,因此具有GET請求的CSRF攻擊應該是無害的。 RFC 7231將POST,PUT和DELETE定義為“不安全”,所有其他方法也被認為是不安全的,以實現最大的保護。
CSRF保護不能防止中間人攻擊,因此使用HTTP Strict Transport Security使用HTTPS。