• Django信息安全相关之CSRF和XSS


    什么是xss攻击

    xss攻击:黑客把恶意的JS脚本提交到后端,后端把恶意脚本渲染显示出来    

    什么是CSRF?

    1、你登录建行官网后 你的浏览器就保存了建行网站的cokie,(如果不关闭这个页面cookie一直生效,就可以发送任何请求)专门在cappron试了一下;

    2、与此同时你 点了其他恶意页面(CSRF攻击的条件)

    3、这个页面携带着你的cokie 伪造你 向到招商银行提交 一个转账form表单你就傻逼了!

    (问题关键:登录某网站之后有了cokie,就可以发送任何请求;这时候最危险)


    如何防止CSRF攻击

    服务端端开启 csrf认证之后,

    客户端发送get请求 要form表单时,在里面加上{% csrf_token %}一个随机字符串

    客户端收到这个 带随机字符串的 form表单之后

    客户端在向服务端 发post请求(不仅要有cokie还检查这个from表单是不是携带{% csrf_token %})
    (不要以为有了cokie就可以随意发送 post请求了!)


    说白了就是:服务端生成随机字符串发给客户端,下次客户端来了要检查他的这个随机字符串

    {% csrf_token %}{
    <QueryDict: {'csrfmiddlewaretoken': ['Vk4rQ7L3d2stscFgHq7lKWTWSEcZrIRAAw3QJv6G2FLopBVJb7sONVbiP9aqDjgj'], 'user': ['我'], 'pwd': ['q'], 'gender': ['1'], 'login': ['yes']}>

    Django应用CSRF

    1.服务端全部禁用CSRF验证

    在项目的setings文件把这个 中间件注释掉

    'django.middleware.csrf.CsrfViewMiddleware',

    2、局部使用

    免除FBV的 CRFS验证

    from django.views.decorators.csrf import csrf_exempt
    @csrf_exempt(免除)
    def login(request):
        if request.method=='GET':
            return render(request,'login.html')
        else:
            print(request.POST)
            return HttpResponse('OK')

    要求FBV使用CRFS验证

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

    3、CBV应用CSRF验证

    要想在CBC局部使用或者禁用CRF验证就必须 导入method_decorator(方法装饰)

    from django.utils.decorators import method_decorator
    @method_decorator(csrf_exempt,name='dispatch')
    class login(View):
        def get(self,request):
            return render(request,'login.html')
    
        def post(self,request):
            return HttpResponse("ok")

    4、from表单添加CSRFtocken

    {% csrf_token %}

     

     

    Ajax应用CSRF

    如果服务端开启了CSRF验证,客户端就发送post请求就必须携带 服务端给的CSRF
    那问题来了如果发 ajanx请求呢?

    答案:客户端发送 get请求时,服务端会把CSRF tocken放在form表单中(隐藏的input标签)发送给客户端

    如果客户端再发post请求给服务端找到这个标签,name="csrfmiddlewaretoken"发送给服务端

    <script src="/static/zhanggen.js"></script>
    </head>
    <body>
    <h1>欢迎来到百合网</h1>
    <form>
        
    {#        服务端开启csrf认证#}
        <p>用户:<input type="text" name="user" ></p>
        <p>密码:<input type="password" name="pwd"></p>
        <p>
            性别:男:<input type="radio" name="gender" value="1" b="1">
                  女:<input type="radio" name="gender" value="2">
        </p>
        <p><input type="checkbox" name="login" value="yes" zhanggen="1">一周免登录</p>
        <input type="button" value="提交" onclick="a()">
    </form>
    </body>
    <script>
        function a(){
            tocken=$('[name="csrfmiddlewaretoken"]').val()
            $.ajax({
                url:'/login/',
                type:'POST',
                data:{'csrfmiddlewaretoken':tocken},
            或者这样data:{'csrfmiddlewaretoken':'{{csrf_token}}'},最后福建小伙向淫王一问
            })
        }
    </script>
    </html>

    2、如果没有from表单携带CSRF的话,不要忘了CSRF的随机字符串也会放在cookie里面哦!!

    从cookie中获取csrftokenf需要借助 jquery.cookie.js插件

    /*!
     * jQuery Cookie Plugin v1.4.1
     * https://github.com/carhartl/jquery-cookie
     *
     * Copyright 2013 Klaus Hartl
     * Released under the MIT license
     */
    (function (factory) {
        if (typeof define === 'function' && define.amd) {
            // AMD
            define(['jquery'], factory);
        } else if (typeof exports === 'object') {
            // CommonJS
            factory(require('jquery'));
        } else {
            // Browser globals
            factory(jQuery);
        }
    }(function ($) {
    
        var pluses = /+/g;
    
        function encode(s) {
            return config.raw ? s : encodeURIComponent(s);
        }
    
        function decode(s) {
            return config.raw ? s : decodeURIComponent(s);
        }
    
        function stringifyCookieValue(value) {
            return encode(config.json ? JSON.stringify(value) : String(value));
        }
    
        function parseCookieValue(s) {
            if (s.indexOf('"') === 0) {
                // This is a quoted cookie as according to RFC2068, unescape...
                s = s.slice(1, -1).replace(/\"/g, '"').replace(/\\/g, '\');
            }
    
            try {
                // Replace server-side written pluses with spaces.
                // If we can't decode the cookie, ignore it, it's unusable.
                // If we can't parse the cookie, ignore it, it's unusable.
                s = decodeURIComponent(s.replace(pluses, ' '));
                return config.json ? JSON.parse(s) : s;
            } catch(e) {}
        }
    
        function read(s, converter) {
            var value = config.raw ? s : parseCookieValue(s);
            return $.isFunction(converter) ? converter(value) : value;
        }
    
        var config = $.cookie = function (key, value, options) {
    
            // Write
    
            if (value !== undefined && !$.isFunction(value)) {
                options = $.extend({}, config.defaults, options);
    
                if (typeof options.expires === 'number') {
                    var days = options.expires, t = options.expires = new Date();
                    t.setTime(+t + days * 864e+5);
                }
    
                return (document.cookie = [
                    encode(key), '=', stringifyCookieValue(value),
                    options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
                    options.path    ? '; path=' + options.path : '',
                    options.domain  ? '; domain=' + options.domain : '',
                    options.secure  ? '; secure' : ''
                ].join(''));
            }
    
            // Read
    
            var result = key ? undefined : {};
    
            // To prevent the for loop in the first place assign an empty array
            // in case there are no cookies at all. Also prevents odd result when
            // calling $.cookie().
            var cookies = document.cookie ? document.cookie.split('; ') : [];
    
            for (var i = 0, l = cookies.length; i < l; i++) {
                var parts = cookies[i].split('=');
                var name = decode(parts.shift());
                var cookie = parts.join('=');
    
                if (key && key === name) {
                    // If second argument (value) is a function it's a converter...
                    result = read(cookie, value);
                    break;
                }
    
                // Prevent storing a cookie that we couldn't decode.
                if (!key && (cookie = read(cookie)) !== undefined) {
                    result[name] = cookie;
                }
            }
    
            return result;
        };
    
        config.defaults = {};
    
        $.removeCookie = function (key, options) {
            if ($.cookie(key) === undefined) {
                return false;
            }
    
            // Must not alter options, thus extending a fresh object...
            $.cookie(key, '', $.extend({}, options, { expires: -1 }));
            return !$.cookie(key);
        };
    
    }));
    View Code


    导入<script src="/static/jquery.cookie.js"></script>

    发送ajax:data:{

    "X-CSRFToken", $.cookie('csrftoken')

    },

    如果是在cookie里面 获取的 CSRF tocken(记号)就不能放在 ajax的请求体里面了

    放在请求头里,而且必须以这个格式(headers:{'X-CSRFToken':tocken},) 这是Django规定

    注意cookie里的 CSRF tocken和 from表单里的不一样

    响应头设置CSRF-Tocken,使用ajax向Django后台发送json数据.

     $.ajax({
                    type: 'POST',
                    async: false,
                    cache: false,
                    url: '{% url "instance_add" %}',
                     headers:{"X-CSRFToken":$.cookie('csrftoken')},
                    contentType: "application/json; charset=utf-8",
                    dataType: "json",
                    traditional:true,
                    data:JSON.stringify({
                        "data_mode_type": $data_mode_type,
                        'database_type': $database_type,
                        'host': $host,
                        'port': $port,
                        'instance_nikename': $instance_nikename,
                        'db_business': $db_business,
                        'DBA': $DBA,
                        'responsible_person': $responsible_person
                    }),
                    success: function (data) {
                       alert(1)
                    }
                });
            })
    ajax
    from django.shortcuts import render,HttpResponse,redirect
    from DB_auto.form_validate.add_dbinfo import dbinfo_create
    import json
    
    def instance_add(request):
        if request.method=='POST':
            json_data=json.loads(request.body.decode('utf-8'))
            obj=dbinfo_create(json_data)
            if obj.is_valid():
                print(obj.cleaned_data)
            else:
                print(obj.errors)
        return render(request,'add_dbinfo.html')
    django后台使用form验证json数据
  • 相关阅读:
    数据结构之内部排序--希尔排序
    数据结构之内部排序--直接插入排序
    MySQL
    力扣115,不同的子序列,动态规划,最大公共子序列问题变形
    算法复习——贪心
    算法复习——分治算法
    为什么我的打印机只能纵向打印不能横向打印
    git创建新的分支
    poj138——建立雷达,贪心,求线段交集
    Oracle数据库学习笔记
  • 原文地址:https://www.cnblogs.com/sss4/p/7106084.html
Copyright © 2020-2023  润新知