做網(wǎng)站哪一部分用到Javaseo教程視頻
目錄
一、csrf跨站請求偽造詳解????????
二、csrf跨域請求偽造
【1】正常服務(wù)端
【2】釣魚服務(wù)端
三、csrf校驗
【介紹】
form表單中進行csrf校驗:
【1】form表單如何校驗
【2】ajax如何校驗
四、csrf相關(guān)裝飾器
【1】csrf_protect裝飾器:
【2】csrf_exempt裝飾器:
【3】FBV中使用上述裝飾器
【4】CBV中使用上述裝飾器
(1)??csrf_protect
(2)??csrf_exempt方法
一、csrf跨站請求偽造詳解????????
- CSRF(Cross-Site Request Forgery)跨站請求偽造是一種常見的網(wǎng)絡(luò)攻擊方式。
- 攻擊者通過誘導受害者訪問惡意網(wǎng)站或點擊惡意鏈接
- 將惡意請求發(fā)送到目標網(wǎng)站上
- 利用受害者在目標網(wǎng)站中已登錄的身份來執(zhí)行某些操作
- 從而達到攻擊的目的。
- 舉個例子
- 假設(shè)受害者在一家網(wǎng)銀網(wǎng)站上登錄賬戶,然后繼續(xù)瀏覽其他網(wǎng)頁。
- 同時,攻擊者通過電子郵件等方式向受害者發(fā)送了一封包含惡意鏈接的郵件。
- 當受害者點擊該鏈接時,潛在的威脅就會變得非?,F(xiàn)實。
- 該鏈接指向一個由攻擊者操縱的網(wǎng)站,該網(wǎng)站上的惡意代碼會自動向網(wǎng)銀網(wǎng)站發(fā)送一個請求,請求轉(zhuǎn)賬到攻擊者的賬戶。
- 由于受害者在網(wǎng)銀網(wǎng)站中已經(jīng)登錄,所以該請求會被認為是合法的,這樣攻擊者就可以成功地進行轉(zhuǎn)賬操作。
- 要保護自己免受CSRF攻擊,網(wǎng)站開發(fā)者可以采取以下措施:
- 使用CSRF令牌:
- 在用戶的請求中添加隨機生成的令牌,并將該令牌保存在用戶會話中。
- 每次提交請求時都會驗證該令牌,以確保請求是合法的。
- 啟用SameSite屬性:
- 將Cookie的SameSite屬性設(shè)置為Strict或Lax,以限制跨站請求。
- 這可以在一定程度上緩解CSRF攻擊。
- 嚴格驗證請求來源:
- 服務(wù)器端可以驗證請求的來源是否為預期的網(wǎng)站域名
- 例如檢查HTTP Referer頭部。
- 使用驗證碼:
- 在敏感操作(如轉(zhuǎn)賬、更改密碼等)上使用驗證碼
- 增加用戶身份驗證的防護。
- 使用CSRF令牌:
二、csrf跨域請求偽造
- 釣魚網(wǎng)站
- 搭建一個類似正規(guī)網(wǎng)站的頁面
- 用戶點擊網(wǎng)站鏈接,給某個用戶打錢
- 打錢的操作確確實實提交給了中國銀行的系統(tǒng),用戶的錢也確實減少
- 但是唯一不同的是,賬戶打錢的賬戶不是用戶想要打錢的目標賬戶,變成了其他用戶
- 內(nèi)部本質(zhì)
- 在釣魚網(wǎng)站的頁面針對對方賬戶,只給用戶提供一個沒有name屬性的普通input框
- 然后在內(nèi)部隱藏一個已經(jīng)寫好帶有name屬性的input框
- 如何避免上面的問題
- csrf跨域請求偽造校驗
- 網(wǎng)站在給用戶返回一個具有提交數(shù)據(jù)功能的頁面的時候會給這個頁面加一個唯一標識
- 當這個頁面后端發(fā)送post請求的時候,我們后端會先校驗唯一標識
- 如果成功則正常執(zhí)行
- 如果唯一標識不符合則拒絕連接(403 forbidden)
- csrf跨域請求偽造校驗
【1】正常服務(wù)端
- 前端
<h1>這是正規(guī)的網(wǎng)站</h1><form action="" method="post"><p>當前賬戶 :>>>> <input type="text" name="start_user"></p><p>目標賬戶 :>>>> <input type="text" name="end_user"></p><p>轉(zhuǎn)賬金額 :>>>> <input type="text" name="money"></p><input type="submit">
</form>
- 后端?
def transform_normal(request):if request.method == "POST":user_start = request.POST.get("start_user")user_end = request.POST.get("end_user")money = request.POST.get("money")return HttpResponse(f"當前賬戶 :>>> {user_start} 向目標用戶 :>>> {user_end} 轉(zhuǎn)賬了 :>>> {money}")return render(request, 'transform_normal.html')
?【2】釣魚服務(wù)端
- 前端
<h1>這是釣魚的網(wǎng)站</h1><form action="http://127.0.0.1:8000/transform_normal/" method="post"><p>當前賬戶 :>>>> <input type="text" name="start_user" ></p><p>目標賬戶 :>>>> <input type="text"></p><p><input type="text" name="end_user" value="Hopes" style="display: none"></p><p>轉(zhuǎn)賬金額 :>>>> <input type="text" name="money"></p><input type="submit">
</form>
- 后端
def transform_normal(request):if request.method == "POST":user_start = request.POST.get("start_user")user_end = request.POST.get("end_user")money = request.POST.get("money")return HttpResponse(f"當前賬戶 :>>> {user_start} 向目標用戶 :>>> {user_end} 轉(zhuǎn)賬了 :>>> {money}")return render(request, 'transform_normal.html')
三、csrf校驗
【介紹】
- csrf校驗是一種用于防止跨站請求偽造(Cross-Site Request Forgery)攻擊的安全措施
form表單中進行csrf校驗:
添加CSRF Token字段:
- 在form表單中添加一個隱藏字段,用于存儲CSRF Token的值。
- 后端服務(wù)器在渲染表單時生成一個CSRF Token,并將其存儲在會話中或者以其他方式關(guān)聯(lián)到當前用戶。
- 當用戶提交表單時,前端將CSRF Token的值包含在請求中。
- 后端在驗證表單數(shù)據(jù)時,檢查請求中的CSRF Token是否與存儲的Token匹配,如果不匹配,則拒絕請求。
設(shè)置Cookie:
- 后端服務(wù)器在渲染表單時,在客戶端設(shè)置一個包含隨機生成的CSRF Token的Cookie。
- 當用戶提交表單時,表單數(shù)據(jù)會被一同發(fā)送到服務(wù)器,并自動包含該Cookie。
- 后端在驗證表單數(shù)據(jù)時,檢查請求中的CSRF Token是否與Cookie中的值匹配,如果不匹配,則拒絕請求。
雙重Cookie校驗:
- 后端服務(wù)器在渲染表單時,在Cookie中設(shè)置一個隨機生成的CSRF Token,并將其存儲在會話中或以其他方式關(guān)聯(lián)到當前用戶。
- 當用戶提交表單時,表單數(shù)據(jù)會被一同發(fā)送到服務(wù)器,請求頭或請求參數(shù)中攜帶一個包含CSRF Token的自定義字段。
- 后端在驗證表單數(shù)據(jù)時,同時檢查請求中的CSRF Token和Cookie中的值是否匹配,如果不匹配,則拒絕請求。
【1】form表單如何校驗
- 在form表單上面加上
csrf_token
{% csrf_token %}
<form action="" method="post"><p>username:<input type="text" name="username"></p><p>transfer_user<input type="password" name="password"></p><p>money<input type="text" name="money"></p><input type="submit">
</form>
- 在頁面標簽中會自動出現(xiàn)一個標簽
<input type="hidden" name="csrfmiddlewaretoken" value="zQaNPZsy1tVmLdqC7GIDOOOfR7yT9YfO58lJ5yrjZfTw2edZTrVYUllOVMnkwXKe">
【2】ajax如何校驗
- 方式一
- 利用標簽查找獲取頁面上的隨機字符串
- 鍵必須叫?
csrfmiddlewaretoken
<button id="b1">ajax請求提交</button><script>$("#b1").click(function () {$.ajax({url: '',type: 'post',// (1) 利用標簽查找獲取頁面上的隨機字符串data: {"username": "dream","csrfmiddlewaretoken":$('[csrfmiddlewaretoken]').val()},success: function () {}})})
</script>
- 方式二
- 利用模板語法進行快捷引入
<button id="b1">ajax請求提交</button><script>$("#b1").click(function () {$.ajax({url: '',type: 'post',// (2) 利用模板語法提供的快捷書寫data: {"username": "dream", "csrfmiddlewaretoken": "{{ csrf_token }}"},success: function () {}})})
</script>
- 方式三
- 定義一個js文件并引入
- 導入該配置文件之前,需要先導入jQuery,因為這個配置文件內(nèi)的內(nèi)容是基于jQuery來實現(xiàn)的
function getCookie(name) {var cookieValue = null;if (document.cookie && document.cookie !== '') {var cookies = document.cookie.split(';');for (var i = 0; i < cookies.length; i++) {var cookie = jQuery.trim(cookies[i]);// Does this cookie string begin with the name we want?if (cookie.substring(0, name.length + 1) === (name + '=')) {cookieValue = decodeURIComponent(cookie.substring(name.length + 1));break;}}}return cookieValue;
}
var csrftoken = getCookie('csrftoken');function csrfSafeMethod(method) {// these HTTP methods do not require CSRF protectionreturn (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}$.ajaxSetup({beforeSend: function (xhr, settings) {if (!csrfSafeMethod(settings.type) && !this.crossDomain) {xhr.setRequestHeader("X-CSRFToken", csrftoken);}}
});
<button id="b1">ajax請求提交</button><script>$("#b1").click(function () {$.ajax({url: '',type: 'post',// (3) 定義外部js文件并引入到本地data: {"username": "dream"},success: function () {}})})
</script>
四、csrf相關(guān)裝飾器
- 網(wǎng)站整體部分校驗csrf,部分不校驗csrf
- 網(wǎng)站整體全部校驗csrf,部分不校驗csrf
【1】csrf_protect裝飾器:
- csrf_protect裝飾器用于需要進行CSRF保護的視圖函數(shù)或類視圖。
- 當一個視圖被csrf_protect裝飾器修飾時,Django會對該視圖接收到的所有POST、PUT、DELETE等非安全HTTP方法的請求進行CSRF校驗。
- 如果請求中沒有有效的CSRF令牌或令牌校驗失敗,Django將返回403 Forbidden響應(yīng)。
【2】csrf_exempt裝飾器:
- csrf_exempt裝飾器用于不需要進行CSRF保護的視圖函數(shù)或類視圖。
- 當一個視圖被csrf_exempt裝飾器修飾時,Django將不會對該視圖接收到的任何請求進行CSRF校驗。
- 這個裝飾器主要用于一些特殊情況,比如與第三方系統(tǒng)進行集成、開放API接口等。
【3】FBV中使用上述裝飾器
from django.views.decorators.csrf import csrf_protect, csrf_exempt
'''
csrf_protect 需要校驗
csrf_exempt 忽視校驗
'''
-
當我們沒有注釋掉
csrf校驗中間件
的時候,可以在函數(shù)頭上加上?@csrf_exempt
?忽視校驗 -
當我們注釋掉
csrf校驗中間件
的時候,可以在函數(shù)頭上加上?@csrf_protect
?強制啟動校驗
【4】CBV中使用上述裝飾器
from django.views.decorators.csrf import csrf_protect, csrf_exempt
'''
csrf_protect 需要校驗針對 csrf_protect 符合之前的裝飾器的三種用法
csrf_exempt 忽視校驗針對 csrf_exempt 只能給 dispatch 方法加才有效
'''
(1)??csrf_protect
- (1) 方式一
- 給指定方法加
@method_decorator
- 給指定方法加
from django.views import View
from django.views.decorators.csrf import csrf_protect, csrf_exempt
from django.utils.decorators import method_decoratorclass MyCsrf(View):def get(self, request):return HttpResponse("get")@method_decorator(csrf_protect)def post(self, request):return HttpResponse("post")
- (2) 方式二
- 給類加然后指明方法?
@method_decorator
- 給類加然后指明方法?
from django.views import View
from django.views.decorators.csrf import csrf_protect, csrf_exempt
from django.utils.decorators import method_decorator@method_decorator(csrf_protect)
class MyCsrf(View):def get(self, request):return HttpResponse("get")def post(self, request):return HttpResponse("post")
- (3) 方式三
- 重寫?
dispatch
?方法
- 重寫?
from django.views import View
from django.views.decorators.csrf import csrf_protect, csrf_exempt
from django.utils.decorators import method_decoratorclass MyCsrf(View):@method_decorator(csrf_protect)def dispatch(self, request, *args, **kwargs):return super(MyCsrf, self).dispatch(request, *args, **kwargs)def get(self, request):return HttpResponse("get")def post(self, request):return HttpResponse("post")
(2)??csrf_exempt
方法
- 只有重寫?
dispatch
方法 有效
from django.views import View
from django.views.decorators.csrf import csrf_protect, csrf_exempt
from django.utils.decorators import method_decoratorclass MyCsrf(View):@method_decorator(csrf_exempt)def dispatch(self, request, *args, **kwargs):return super(MyCsrf, self).dispatch(request, *args, **kwargs)def get(self, request):return HttpResponse("get")def post(self, request):return HttpResponse("post")