CSRFjavascript
Cross Site Request Forgery 跨站域請求僞造html
CSRF 攻擊能夠在受害者絕不知情的狀況下以受害者名義僞造請求發送給攻擊站點,從而在並未受權的狀況下執行在權限保護之下的操做。java
攻擊流程:ajax
1,受害者登陸招商銀行網站進行了一些正常的操做django
2,受害着在未關閉招商銀行網站的狀況下,打開了一個被黑客控制的網站瀏覽器
3,釣魚網站會引誘受害者觸犯轉帳請求安全
4,銀行處理請求,錢就沒有 了服務器
CSRF 攻擊的對象cookie
在討論防護CSRF以前,先要明確CSRF攻擊的對象,也就是須要保護的對象。session
CSRF攻擊是藉助受害者的cookie騙取服務器的信任,可是黑客並不能拿到cookie,也看不到cookie內容。
另外,對於服務器返回的結果,因爲瀏覽器同源策略的限制,黑客也沒法進行解析。所以黑客沒法從返回的結果中獲得任何東西,他所能作到的就是給服務器發送請求,以執行請求中所描述的命令,在服務器端直接改變數據的值,而非竊取服務器中的數據。因此,要保護的對象是那些能夠直接產生數據改變的服務,而對於讀取數據的服務,則不須要進行CSRF的保護。
防護策略
在請求地址中添加token並驗證
CSRF攻擊之因此可以成功,是由於黑客能夠徹底僞造用戶的請求,該請求中全部的用戶驗證信息都是存在於cookie中,所以黑客能夠在不知道驗證信息的狀況下直接利用用戶本身的cookie來經過安全驗證。要抵禦CSRF關鍵在於在請求中添加黑客不能僞造的信息,而且該信息不存在cookie中。
能夠在http請求中以參數的形式加入一個隨機產生的token,並在服務器端創建一個攔截器來驗證這個token,若是請求中沒有token或者token內容不正確,則認爲多是CSRF攻擊而拒絕該請求。
token能夠在用戶登錄後產生放在session中,而後在每次請求時把token從session中拿出,與請求中的token進行對比,但這種方法的難點在於如何把token以參數的形式加入請求。
對於GET請求,token將附近在請求地址以後,這樣URL就變成了 http://url?csrftoken=tokenvalue
對於POST請求, 要在form的最後加上 <input type="hidden" name="csrftoken" value="tokenvalue" />
這樣就包token以參數的形式加入請求了。
可是,在一個網中,能夠接受請求的地方很是多,要對於每個請求都加上token是很麻煩的,而且很容易遺漏,一般使用的方式就是在每次頁面加載時,使用javascript遍歷整個dom樹,對於dom中全部a 和 form標籤後加入token。
這樣就能夠解決大部分的請求,可是對於在頁面加載以後動態生成的html代碼,這種方法就沒有做用了,還須要程序在編碼時手動添加token。
Django中使用CSRF
使用方法:
1,CSRF的中間件是在 MIDDLEWARE_CLASSES 中默認激活的。‘django.middleware.csrf.CsrfViewMiddleware’,能夠禁用,可是這裏是不推薦的,可使用 csrf_protect()方法。
2,在form表單後面添加 csrf_token 例如:
<form action="" method="post"> {% csrf_token %}
CSRF AJAX
獲取token
1 // using jQuery 2 function getCookie(name) { 3 var cookieValue = null; 4 if (document.cookie && document.cookie != '') { 5 var cookies = document.cookie.split(';'); 6 for (var i = 0; i < cookies.length; i++) { 7 var cookie = jQuery.trim(cookies[i]); 8 // Does this cookie string begin with the name we want? 9 if (cookie.substring(0, name.length + 1) == (name + '=')) { 10 cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); 11 break; 12 } 13 } 14 } 15 return cookieValue; 16 } 17 var csrftoken = getCookie('csrftoken');
上面的代碼能夠經過使用 javascript 的cookie庫中的 getcookie 簡化
1 var csrftoken = Cookies.get('csrftoken');
ajax:
function csrfSafeMethod(method) { // these HTTP methods do not require CSRF protection return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); } $.ajaxSetup({ beforeSend: function(xhr, settings) { if (!csrfSafeMethod(settings.type) && !this.crossDomain) { xhr.setRequestHeader("X-CSRFToken", csrftoken); } } });