zoukankan      html  css  js  c++  java
  • Django-CSRF跨站请求伪造防护

    前言

    CSRF全称Cross-site request forgery(跨站请求伪造),是一种网络的攻击方式,也被称为“One Click Attack”或者Session Riding,通常缩写为CSRF或者XSRF。

    攻击原理

    1、用户访问正常的网站A,浏览器就会保存网站A的cookies。

    2、用户在访问恶意网站B, 网站B上有某个隐藏的链接会自动请求网站A的链接地址,例如表单提交,传指定的参数。

    3、恶意网站B的自动化请求,执行就是在用户A的同一个浏览器上,因此在访问网站A的时候,浏览器会自动带上网站A的cookies。

    4、所以网站A在接收到请求之后,可判断当前用户登录状态,所以根据用户的权限做具体的操作逻辑。

    防范措施

    1、在指定表单或者请求头的里面添加一个随机值做为参数。

    2、在响应的cookie里面也设置该随机值。

    3、用户正常提交表单的时候会默认带上表单中的随机值,浏览器会自动带上cookie里面的随机值,那么服务器下次接受到请求之后就可以取出两个值进行校验。

    4、对于网站B来说网站B在提交表单的时候不知道该随机值是什么,所以就形成不了攻击。

    Django中CSRF中间件

    django在创建项目的时候,默认就会有添加中间进行CSRF的保护,在MIDDLEWARE可以看到加载了 django.middleware.csrf.CsrfViewMiddleware 的中间件,这里是全局设置,也可以局部设置。

    全局保护:直接启用中间件就可以了。

    局部保护: from django.views.decorators.csrf import csrf_exempt,csrf_protect ,使用装饰器进行验证。

     csrf_protect :为当前函数强制设置防跨站请求伪造功能,即便settings中没有设置全局中间件;

     csrf_exempt :取消当前函数防跨站请求伪造功能,即便settings中设置了全局中间件。

    验证

    在POST请求提交数据的时候,django会去检查是否有一个csrf的随机字符串,如果没有就会返回403没有权限访问。

    表单验证

    在form表单里面需要添加{%csrf_token%},Django会自动渲染隐藏的input输入框:

    <input type="hidden" name="csrfmiddlewaretoken" value="2Sb0DQwDVgOQ8i3n1BaG1MUPLEYr6ZGaCLYa14maOQM0Ami5ddQOR6hfXuD2mrmA">

    在表单提交的时候,中间件会验证csrfmiddlewaretoken。

    通过ajax提交

    通过cookies获取到csrftoken,

    function getCookie(name) {
        var r = document.cookie.match("\b" + name + "=([^;]*)\b");
        return r ? r[1] : undefined;
    }
    $.ajax({
        url:"/api/v1.0/orders",
        type:"POST",
        data: JSON.stringify(data),
        contentType: "application/json",
        dataType: "json",
        headers:{
            "X-CSRFtoken":getCookie("csrf_token"),
        },

    局部禁用或者启用

    1、如果是函数视图,可以直接在函数加上装饰器即可

    from django.views.decorators.csrf import csrf_exempt,csrf_protect
    @csrf_exempt
    def login(request):
        if request.method == 'GET':
            return render(request,'login.html')
        else:
            return HttpResponse('ok')

    2、如果是类视图,需要使用方法装饰器进行封装

    from django.utils.decorators import method_decorator
    from django.views.decorators.csrf import csrf_exempt,csrf_protect
    from django.views.generic import TemplateView
    
    @method_decorator(csrf_exempt)
    class LoginView(TemplateView):
        template_name = 'login.html'
        def post():
            return HttpResponse('ok')

    3、直接装饰as_view()方式,在URLconf里面设置。

    from django.views.decorators.csrf import csrf_exempt,csrf_protect
    
    urlpatterns = [
        path('login/', csrf_exempt(LoginView.as_view()),name="login"),
    ]
  • 相关阅读:
    二叉堆(最小堆, 最大堆)介绍与实现
    C++ 用变量定义数组
    C++ 用变量定义数组
    053185
    053184
    053183
    053182
    053181
    053180
    oracle prior
  • 原文地址:https://www.cnblogs.com/tangkaishou/p/10284001.html
Copyright © 2011-2022 走看看