【1】什么是CSRF
CSRF全称是跨站请求伪造。这是一种网络攻击方式,攻击者通过伪造用户请求来达到非法操作的目的。
CSRF 就像是攻击者利用了被攻击者的身份,通过伪装成被攻击者的身份,在被攻击者不知情的情况下执行操作。
攻击者通过诱使用户访问恶意网站或点击恶意链接,从而触发用户浏览器发送针对目标应用程序的请求。这种攻击方式不会直接获取用户的敏感信息,而是利用用户当前的身份在目标应用程序上执行操作。
- 说白了就是为用为了上学用了别人的名字来到达我上学的目的
内部的本质
- 我们在钓鱼网站的页面 针对对方账户 只给用户提供一个没有nane属性的普通input框然后为什么在内部隐藏一个已经写好name和value的input框。
CSRF 可以做什么?
你这可以这么理解CSRF攻击:攻击者盗用了你的身份,以你的名义发送恶意请求。 CSRF能够做的事情包括:以你名义发送邮件,发消息,盗取你的账号,甚至于购买商品,虚拟货币转账...造成的问题包括:个人隐私泄露以及财产安全。
CSRF 解决方法
有许多有效的方法可以预防和缓解 CSRF 攻击。从用户的角度来看,预防是维护登录凭据并拒绝未经授权的参与者访问应用程序的问题。
最佳实践如下:
- 当不使用时登出 Web 应用程序
- 确保用户名和密码
- 不允许浏览器记住密码
- 登录到应用程序时避免同时浏览
对于 Web 应用程序,存在多种解决方案来阻止恶意流量并防止攻击。最常见的缓解方法之一是为每个会话请求或 ID 生成唯一的随机令牌。这些服务器随后由服务器检查和验证。具有重复令牌或缺失值的会话请求被阻止。或者,不匹配其会话 ID 令牌的请求是阻止到达应用程序的。
双重提交 Cookie 是阻止 CSRF 的另一种众所周知的方法。类似于使用唯一令牌,随机令牌被分配给 cookie 和请求参数。然后,服务器在授予对应用程序的访问之前验证令牌是否匹配。
虽然有效,但可以在许多点上公开代币,包括在浏览器历史记录中,HTTP 日志文件,网络设备记录 HTTP 请求的第一行和引用器标头(如果受保护的站点链接到外部 URL)。这些潜在的弱点使代币成为一个不隔热的解决方案。
【2】CSRF跨站请求伪造校验
CSRF校验是一种防止跨站请求伪造攻击的机制,它通过验证请求中包含的CSRF令牌来确认请求的合法性。
- 网站在给用户返回一个具有提交数据功能页面的时候会给这个页面加一个唯一标识。
- 当这个页面朝后发送post请求的时候 我的后端会先校验唯一标识, 如果唯一标识不对直接拒绝(403 forbbiden)如果成功则正常执行。
【3】Ajax携带CSRF
(1)方式一:获取标签值
- 利用标签查找获取页面上的随机字符串
- 键必须叫
csrfmiddlewaretoken
html
<button id="b1">ajax请求提交</button>
<script>
$("#b1").click(function () {
$.ajax({
url: '',
type: 'post',
// (1) 利用标签查找获取页面上的随机字符串
data: {
"username": "dream",
"csrfmiddlewaretoken": $("input[name='csrfmiddlewaretoken']").val()
},
success: function () {
}
})
})
</script>
(2)方式二:模板语法取值
- 利用模板语法进行快捷引入
html
<button id="b1">ajax请求提交</button>
<script>
$("#b1").click(function () {
$.ajax({
url: '',
type: 'post',
// (2) 利用模板语法提供的快捷书写
data: {
"username": "dream",
"csrfmiddlewaretoken": "{{ csrf_token }}"
},
success: function () {
}
})
})
</script>
(3)方式三:导入js文件
python
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 protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
beforeSend: function (xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
});
html
<button id="b1">ajax请求提交</button>
<script src="{% static 'js/csrf_check.js' %}"></script>
<script>
$("#b1").click(function () {
$.ajax({
url: '',
type: 'post',
// (3) 定义外部js文件并引入到本地
data: {
"username": "dream"
},
success: function () {
}
})
})
</script>
【4】CSRF相关装饰器
在使用csrf校验时,我们可能会遇到如下两种需求:
python
整个django项目都校验csrf 但是某些个视图函数\类不想校验
整个django项目都不校验csrf 但是某些个视图函数\类需要校验
这时候可以给视图函数、视图类添加装饰器来实现需求。
FBV添加装饰器的方式
与正常函数添加装饰器一致。
python
from django.views.decorators.csrf import csrf_exempt, csrf_protect
# @csrf_exempt
@csrf_protect
def transfer_func(request):pass
被csrf_protect
装饰的函数,添加crsf校验。
被csrf_exempt
装饰的函数,免除crsf校验。
CBV添加装饰器的方式
与正常情况不一样 需要注意。需要额外导入method_decorator
。
主要有三种方式:
python
from django.views.decorators.csrf import csrf_exempt, csrf_protect
rom django.utils.decorators import method_decorator
# @method_decorator(csrf_protect, name='post') # 方式2:单独生效
class MyView(views.View):
@method_decorator(csrf_protect) # 方式3:整个类中生效
def dispatch(self, request, *args, **kwargs):
return super().dispatch(request, *args, **kwargs)
# @method_decorator(csrf_protect) # 方式1:单独生效
def post(self, request):
return HttpResponse('from cbv post view')
CBV添加装饰器时,注意有一个装饰器是特例只能有一种添加方式>>>:csrf_exempt
只有在dispatch方法添加才会生效
方式1:装饰类中方法
这里表示对post请求添加csrf校验。
方式2:装饰整个类
装饰整个类时,需要传入参数,申明装饰的是类中哪个方法,是需要添加csrf校验,还是免除csrf校验。
这里还是对post请求添加csrf校验。
方式3:装饰dispatch方法
我们在自己的视图类中,写一个dispatch方法,再使用super调用父类的dispatch,最后给dispatch方法添加装饰器。
装饰dispatch方法时,会对类中所有方法生效。
这里表示对视图类中所有方法都添加csrf校验。
特例 csrf_exempt
在全局crsf校验打开的情况下:我们想让我们的CBV不校验crsf。
如下图所示:csrf_exempt只有在dispatch方法添加才会生效
ogs.com/blog/2614258/202212/2614258-20221226225446900-2084964817.png)
如下图所示:csrf_exempt只有在dispatch方法添加才会生效