django-csrf攻击

csrf(Cross Site Request Forgery, 跨站域请求伪造)

csrf攻击

CSRF 攻击是黑客借助受害者的 cookie 骗取服务器的信任,但是黑客并不能拿到 cookie,也看不到 cookie 的内容。另外,对于服务器返回的结果,由于浏览器同源策略的限制,黑客也无法进行解析。因此,黑客无法从返回的结果中得到任何东西,他所能做的就是给服务器发送请求,以执行请求中所描述的命令,在服务器端直接改变数据的值,而非窃取服务器中的数据 。黑客无法获取cookie和session值更无法进行解析。

xss与csrf区别

马三立小品〈逗你玩〉中的小偷就利用xss突破了防盗系统。

防盗系统启动:

妈妈:给我看着衣服
小孩:好的

小偷来

正常工作:
小孩:你是谁?
小偷:我叫张三
小孩:妈妈,有人偷衣服
妈妈:谁?
小孩:张三
小偷被捉

漏洞:
小孩:你是谁?
小偷:我叫逗你玩
小孩:妈妈,有人偷衣服
妈妈:谁?
小孩:逗你玩
妈妈:。。。

csrf是让用户在不知情的情况,冒用其身份发起了一个请求
小偷:你妈妈喊你去买洗衣粉


实例来源:作者:李上天  来源:知乎

防御策略:在请求地址中添加 token 并验证

CSRF 攻击之所以能够成功,是因为黑客可以完全伪造用户的请求,该请求中所有的用户验证信息都是存在于 cookie 中,因此黑客可以在不知道这些验证信息的情况下直接利用用户自己的 cookie 来通过安全验证。要抵御 CSRF,关键在于在请求中放入黑客所不能伪造的信息,并且该信息不存在于 cookie 之中。可以在 HTTP 请求中以参数的形式加入一个随机产生的 token,并在服务器端建立一个拦截器来验证这个 token,如果请求中没有 token 或者 token 内容不正确,则认为可能是 CSRF 攻击而拒绝该请求。

token 可以在用户登陆后产生并放于 session 之中,然后在每次请求时把 token 从 session 中拿出,与请求中的 token 进行比对,但这种方法的难点在于如何把 token 以参数的形式加入请求。对于 GET 请求,token 将附在请求地址之后,这样 URL 就变成 http://url?csrftoken=tokenvalue。 而对于 POST 请求来说,要在 form 的最后加上 <input type=”hidden” name=”csrftoken” value=”tokenvalue”/>,这样就把 token 以参数的形式加入请求了。但是,在一个网站中,可以接受请求的地方非常多,要对于每一个请求都加上 token 是很麻烦的,并且很容易漏掉,通常使用的方法就是在每次页面加载时,使用 javascript 遍历整个 dom 树,对于 dom 中所有的 a 和 form 标签后加入 token。这样可以解决大部分的请求,但是对于在页面加载之后动态生成的 html 代码,这种方法就没有作用,还需要程序员在编码时手动添加 token。

一,form表单提交

<form action="/login/" method="POST">
    {#         {{ csrf_token }}#}
{{ csrf_token }}表示随机字符串交给服务端通过测试并隐藏在页面的input中 {% csrf_token %} {# 随机字符串隐藏在页面中的<input>中发送给后台#} <input type="text" name="user"/> <input type="text" name="pwd"/> <input type="submit" value="提交"/> </form>

二,ajax提交

$(function () {

{#            在Ajax请求前设置请求头#}
            $.ajaxSetup({
                beforeSend: function (xhr, settings) {
                    xhr.setRequestHeader('X-CSRFtoken', $.cookie('csrftoken'));
                }
            });

            $('#btn').click(function () {
                $.ajax({

{#                    关于ajax中data#}
{#                    第一个data就是发送给服务端的数据,success里面的data是服务器返回的数据#}

                    url: '/login',
                    type:'POST',
                    data:{'user':'root', "pwd":'123'},
                    headers:{'X-CSRFtoken': $.cookie('csrftoken')},
{#                    请求头中不能出现下划线否则视为非法#}
                    success: function (data) {
                        console.log(data);
                        alert(data);
                    },
                    error: function (data) {
                      alert(data);
                    }
                    }
                )
            })
        });


对于Ajax提交时通常还需要对提交请请求的方法进行判断如果是get,head,options,trace方法,不会改变数据,CSRF 攻击
无法解析服务器返回的结果,无需保护。则不需要进行携带csrftoken所以请求前需要进行判断、
<script type="text/javascript">
        var csrftoken = $.cookie('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);
                }
            }
        });
        function Do(){

            $.ajax({
                url:"/app01/test/",
                data:{id:1},
                type:'POST',
                success:function(data){
                    console.log(data);
                }
            });

        }
</script>

 参考链接:https://www.cnblogs.com/chenchao1990/p/5339779.html

猜你喜欢

转载自www.cnblogs.com/welan/p/9011073.html