"""
钓鱼网站搭建一个跟正规网站一摸一样的界面(中国银行)用户进入到我们的网站,用户给某人打钱,用户打钱操作确确实实是提交给了中国银行的系统,用户的钱也确确实实减少了,但是唯一不同是打钱的账户不是用户想要打的账户,变成了另一个账户内部本质:在钓鱼网站的页面,针对对方账户,只给用户提供一个没有name属性的input框,然后我们再内部隐藏一个已经写好name和value的input框,"""
真正的网站端口:8000
http://127.0.0.1:8000
# 注释掉csrf'django.middleware.csrf.CsrfViewMiddleware',
中国银行
# views.py
def transfer(request):if request.method == 'POST':username = request.POST.get('username')target_user = request.POST.get('target_user')money = request.POST.get('money')print('%s给%s转了%s元' % (username, target_user, money))return render(request, 'transfer.html')# urls.py
path('transfer/',views.transfer)
钓鱼网站模拟端口:8001
#不用注释csfr
phishing site
#views.py
def transfer(request):return render(request,'transfer.html')# urls.py
path('transfer/',views.transfer)
如何规避上述问题:
csrf跨站请求伪造
网站再给用户返回一个提交数据功能的页面的时候会给这个页面加一个唯一标识
当这个页面朝后端发post请求的时候,后端会先校验唯一标识,如果唯一标识不对,直接拒绝(403 forbiden),如果成功则正常执行
#开启配置文件里的csrf中间件
再次发送请求
钓鱼网站再次发送请求
不论是ajax还是谁,只要是向我Django提交post请求的数据,都必须校验csrf_token来防伪跨站请求
通过获取隐藏的input标签中的csrfmiddlewaretoken
值,放置在data中发送
中国银行
中国银行
先拷贝js文件:
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);}}
});
将文件配置到静态文件中,在html页面上通过导入该文件即可自动帮我们解决ajax提交post数据时校验csrf_token的问题
中国银行
{% load static %}
#配置文件中开始csrf中间件,
from django.views.decorators.csrf import csrf_protect, csrf_exempt"""
csrf_protect,需要校验
csrf_exempt 忽视校验
"""@csrf_exempt
def transfer(request):if request.method == 'POST':username = request.POST.get('username')target_user = request.POST.get('target_user')money = request.POST.get('money')print('%s给%s转了%s元' % (username, target_user, money))return render(request, 'transfer.html')
# 注释掉form表单中 {% csrf_token %}#}
#关闭配置文件中csrf中间件@csrf_protect
def transfer(request):if request.method == 'POST':username = request.POST.get('username')target_user = request.POST.get('target_user')money = request.POST.get('money')print('%s给%s转了%s元' % (username, target_user, money))return render(request, 'transfer.html')
csrf_protect,需要校验
针对csrf_protect符合CBV装饰器的三种写法csrf_exempt 忽视校验
针对csrf_protect只能给dispatch方法加才有效
# views.py
from django.utils.decorators import method_decorator
from django.views import View# @method_decorator(csrf_protect,name='post') #第二种
class MycsrfToken(View):@method_decorator(csrf_protect)def dispatch(self, request, *args, **kwargs):return super(MycsrfToken, self).dispatch(request, *args, **kwargs)def get(self, request):return HttpResponse('get')# @method_decorator(csrf_protect) #第一种方式可以def post(self, request):return HttpResponse('post')# urls.pypath('csrf/', views.MycsrfToken.as_view()),
# html from表单向csrf路由提交
中国银行
# urls.py
path('transfer/', views.transfer),# views.py
def transfer(request):if request.method == 'POST':username = request.POST.get('username')target_user = request.POST.get('target_user')money = request.POST.get('money')print('%s给%s转了%s元' % (username, target_user, money))return render(request, 'transfer.html')
from django.utils.decorators import method_decorator
from django.views import View# @method_decorator(csrf_exempt,name='dispatch')
class MycsrfToken(View):@method_decorator(csrf_exempt)def dispatch(self, request, *args, **kwargs):return super(MycsrfToken, self).dispatch(request, *args, **kwargs)def get(self, request):return HttpResponse('get')def post(self, request):return HttpResponse('post')
上一篇:二级导航栏
下一篇:网络线缆连接器和线槽