Django的CSRF介绍

1、CSRF介绍

CSRF(Cross-Site Request Forgery,跨站点伪造请求)是一种网络攻击方式,该攻击可以在受害者毫不知情的情况下以受害者名义伪造请求发送给受攻击站点,从而在未授权的情况下执行在权限保护之下的操作,具有很大的危害性。具体来讲,可以这样理解CSRF攻击:攻击者盗用了你的身份,以你的名义发送恶意请求,对服务器来说这个请求是完全合法的,但是却完成了攻击者所期望的一个操作,比如以你的名义发送邮件、发消息,盗取你的账号,添加系统管理员,甚至于购买商品、虚拟货币转账等。

2、csrf攻击过程

csrf攻击说明
1.用户C打开浏览器,访问受信任网站A,输入用户名和密码请求登录网站A;
2.在用户信息通过验证后,网站A产生Cookie信息并返回给浏览器,此时用户登录网站A成功,可以正常发送请求到网站A;
3.用户未退出网站A之前,在同一浏览器中,打开一个TAB页访问网站B;
4.网站B接收到用户请求后,返回一些攻击性代码,并发出一个请求要求访问第三方站点A;
5.浏览器在接收到这些攻击性代码后,根据网站B的请求,在用户不知情的情况下携带Cookie信息,向网站A发出请求。网站A并不知道该请求其实是由B发起的,所以会根据用户C的Cookie信息以C的权限处理该请求,导致来自网站B的恶意代码被执行。

csrf的攻击之所以会成功是因为服务器端身份验证机制可以通过Cookie保证一个请求是来自于某个用户的浏览器,但无法保证该请求是用户允许的。因此,预防csrf攻击简单可行的方法就是在客户端网页上添加随机数,在服务器端进行随机数验证,以确保该请求是用户允许的。Django也是通过这个方法来防御csrf攻击的。

转自(原文链接:http://www.jianshu.com/p/a178f08d9389)

2、Django中使用CSRF

1)防护机制

django 第一次响应来自某个客户端的请求时,会在服务器端随机生成一个 token,把这个 token 放在 cookie 里。然后每次 POST 请求都会带上这个 token,这样就能避免被 CSRF 攻击。

  1. 在返回的 HTTP 响应的 cookie 里,django 会为你添加一个 csrftoken 字段,其值为一个自动生成的 token
  2. 在所有的 POST 表单时,必须包含一个 csrfmiddlewaretoken 字段 (只需要在模板里加一个 tag, django 就会自动帮你生成,见下面)
  3. 在处理 POST 请求之前,django 会验证这个请求的 cookie 里的 csrftoken 字段的值和提交的表单里的 csrfmiddlewaretoken 字段的值是否一样。如果一样,则表明这是一个合法的请求,否则,这个请求可能是来自于别人的 csrf 攻击,返回 403 Forbidden.
  4. 在所有 ajax POST 请求里,添加一个 X-CSRFTOKEN header,其值为 cookie 里的 csrftoken 的值

2)使用介绍 首先要启用 django.middleware.csrf.CsrfViewMiddleware 这个中间件 再次,在所有的 POST 表单元素时,需要加上一个 {% csrf_token %} tag。GET请求不需要进行保护。

后台实现csrf的方法有两种:

1、使用RequestContext,它会始终使用'django.template.context_processors.csrf'(无论 TEMPLATES 设置中配置的是什么模板上下文处理器)。如果你正在使用通用视图或Contrib 中的应用,你就不用担心了,因为这些应用通篇都使用RequestContext。

2、手工导入并使用处理器来生成CSRF token,并将它添加到模板上下文中。例如:

from django.shortcuts import render_to_response  
from django.template.context_processors import csrf

def my_view(request):  
    c = {}c.update(csrf(request))# ... view code herereturn render_to_response("a_template.html", c)

前端:

1.在表单当中附加csrftoken tag, 2.通过request请求中添加X-CSRFToken请求头。

注意:Django默认对所有的POST请求都进行csrftoken验证,若验证失败则403错误侍候。

1、表单当中附加csrftoken 主要引入CSRF上下文: {{csrf_token}}。

2、通过request请求中添加X-CSRFToken请求头

  $('#login-form').submit(function(){
    $.ajax({
        type:"POST",
        url:"/logins/",
        data:{"username":$("#login-username").val(),"password":$("#login-password").val()},
        beforeSend:function(xhr){
            xhr.setRequestHeader("X-CSRFToken", $.cookie('csrftoken'));
        },
        success:function(data,textStatus){
            var errors = data["errors"];
            if(errors.length==0){
                location.reload();
            }
            else{
                //alert(errors);
                var html = "<div class=\"alert alert-danger\">"
                for (var key in errors){
                    html += errors[key]+"<br/>";
                }
                html += "</div>";
                $("#login-modal .modal-header").after(html);
            }
        },
        error:function(XMLHttpRequest, textStatus, errorThrown){
            alert(XMLHttpRequest.responseText);
        }

    });
    return false;
});
--------EOF---------
微信分享/微信扫码阅读