• Python菜鸟之路:Django CSRF跨站请求伪造


    前言

      CSRF,Cross-site request forgery跨站请求伪造,也被称为“One Click Attack”或者Session Riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。他的产生由来是因为浏览器引起的。 比如用户访问A网站,A网站的html代码中有个提交数据,是发往B网站的,B网站受到浏览器发来的请求,实际上已经处理完毕,并且将返回数据发回了。但是这段数据在到达用户浏览器的时候,被浏览器拦截抛弃,这种现象是CSRF的由来。

      也有部分人利用CSRF进行相关攻击,攻击原理如下:

       

    Django中的CSRF

      在Django中,有个中间件叫做django.middleware.csrf.CsrfViewMiddleware,如果加载后,在什么都不配置的情况下,跨站请求就会被阻挡,报错CSRF的错误。

      解决上述问题,有两种方法,一种是在html中书写: {% csrf_token %}。另外一种是为每次ajax请求设置cookie

     方法一:HTML中书写

    <form action="/csrf/" method="post">
            {% csrf_token %}
            <input type="text" name="v">
            <input type="submit" value="提交">
        </form>
    

      上述的{% csrf_token %}在页面中,会转换成input标签,标签中的内容类似如下:

    <input type="hidden" name="csrfmiddlewaretoken" value="FS187YU8N8ixAOskUHTAEtkq0xJ3dirS2yJrCnN5IpAY9B9qpVHAQOhxoC4iV614">
    

      这样的话,这次访问过去的请求的header中,就会带有csrftoken=QRzJCWrjRzJxHnG3phk1Nx60f96jfie7bILMEOi9gNEXTs6Mf9N6JyWzqJUMRogn的cookie,这样就不会受到浏览器的阻碍。

      

      但是这么做是有弊端的。因为这段value字符串,在机器A可以用,如果在机器B上用,Django也会认为是合法的。

      在书写的时候,路由函数也要注意使用render!!!

    def csrf(request):
    
        return render(request,'csrf.html')
    

    方法二:为每次ajax请求设置cookie

      通常我们的请求都是以ajax方式来提交的。因此这种方法更加需要明白。不多废话,直接贴代码

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
            <form action="/csrf/" method="post">
                {% csrf_token %}
                <input type="text" name="v" />
                <input type="submit" value="提交" />
            </form>
    
            <input type="button"  value="Ajax提交" onclick="DoAjax();" />
            <script src="/static/jquery-2.1.4.min.js"></script>
            <script src="/static/jquery.cookie.js"></script>
        <script>
            // 去cookie中获取值
            var csrftoken = $.cookie('csrftoken');
    
            function csrfSafeMethod(method) {
                // these HTTP methods do not require CSRF protection
                return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
            }
            $.ajaxSetup({  //当所有的ajax请求发送之前,进行这样的配置
                beforeSend: function(xhr, settings) {
                    if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
                        xhr.setRequestHeader("X-CSRFToken", csrftoken);
                    }
                }
            });
            function DoAjax(){
                $.ajax({
                    url: '/csrf/',
                    type: 'POST',
                    data: {'k1': 'v1'},
                    success: function (data) {
                        console.log(data);
                    }
                })
            }
        </script>
    
    </body>
    </html>

      上述的本质,就是去浏览器的cookie中获取csrftoken,在发送ajax请求的header的cookie中,加入csrftoken。

    CSRF的单独使用

      通常情况下,在settings的文件中,载入csrf的配置后,CSRF会对全局的url产生效果。那么,如果在settings中没有加载CSRF,CSRF还能使用么?答案是肯定的。

      from django.views.decorators.csrf import csrf_exempt,csrf_protect

    • @csrf_protect,为当前函数强制设置防跨站请求伪造功能,即便settings中没有设置全局中间件。
    • @csrf_exempt,取消当前函数防跨站请求伪造功能,即便settings中设置了全局中间件。
  • 相关阅读:
    poj 2046 Power Strings KMP
    谈谈需求变更的用户签字确认问题
    Oracle 10g客户端 安装(配图)
    如何让有能力的下属承担更多职责
    软件性能测试工具在测试工作中的重要性
    Oracle 10g 服务器端 安装图解
    JS 操作页面基础操作:禁止另存 防止复制 防止选择
    Javascript 长整型 转 C# DateTime
    配置AJAX Enabled WCF在hosting时: Showing the serviceMetadata in an ASP.NET AJAX Service
    ICON资源网站
  • 原文地址:https://www.cnblogs.com/jishuweiwang/p/5950166.html
Copyright © 2020-2023  润新知