CSRF攻击原理&Django的应用方法

CSRF攻击原理

Cross Site Request Forgery 跨站请求伪造

一句话总结:都是cookie惹的祸,所以先看看cookie

cookie的作用流程

当输入一串网址登陆一个安全的站点如:www.XXX.com,并登陆到你的账号,服务器就会分配一个cookie给浏览器,里面包含了认证的信息,用户在这个站点打开其他的网页时将就不用再输入用户名和密码,浏览器会自动将这个cookie的值包含到请求中。服务器收到请求后,验证cookie的值是否和自己保存的值相同,如果是就证明用户身份合法,允许进行下一步的操作。这样做的好处就是简化的用户操作,不用没进行一步就要输入用户名密码 。

因为每个用户的生成的cookie都不同,cookie正确的话服务器可以认为对端是真实的用户。

然而,坏就坏在请求不一定是用户在了解的情况下发送的,这样对于这些请求浏览器也会带上cookie,服务器就仍然将它作为正常的消息处理,csrf正是利用了这一点,具体流程如下描述。

CSRF的攻击流程

user A 使用浏览器访问可信的网站website1进行业务,此时浏览器会保存website1相关的cookie

user A 使用浏览器访问一个不可信站点website2,如果website2中的网页具有指向website1的链接,攻击就有可能发生。有如下几种情况:

a、website2返回给用户的页面包含website1的链接,点击这个链接就会跳转到website1

b、website2返回给用户的页面包含<img src='XXX'>,其中XXX就是指向website1的链接,这样用户只要访问website2的页面就被攻击了,因为浏览器会解析<img src='XXX'>标签,自动获取XXX的’图片内容‘

c、website2返回给用户的页面包含自动加载的js,且js中有跳转到website1的动作,同上,用户只要访问website2就被攻击了

a、b、c三总跳转的方式不同但是利用的原理是一样的,那就是用户在本地还保存这website1的cookie,再次通过website2上的链接请求website1时,浏览器就会自动将website1对应的cookie加上,这样website1就会认为这个请求是用户合法请求而进行处理。

website2上的攻击者就可以通过编写特定的请求内容,进行攻击


Django的解决方法

Django预防CSRF攻击的方法是在用户提交的表单中加入一个csrftoken的隐含值,这个值和服务器中保存的csrftoken的值相同,这样做的原理如下:

1、在用户访问django的可信站点时,django反馈给用户的表单中有一个隐含字段csrftoken,这个值是在服务器端随机生成的,每一次提交表单都会生成不同的值

2、当用户提交django的表单时,服务器校验这个表单的csrftoken是否和自己保存的一致,来判断用户的合法性

3、当用户被csrf攻击从其他站点发送精心编制的攻击请求时,由于其他站点不可能知道隐藏的csrftoken字段的信息这样在服务器端就会校验失败,攻击被成功防御

具体配置如下:

template中添加{%csrf_token%}标签

    <form enctype="multipart/form-data" action="/wxroot/JS/upload_file/" method="post">  
    {% csrf_token %}
       <input type="file" name="myfile" />  
       <br/>  
       <input type="submit" value="upload"/>  
    </form>


如果是js提交的post请求,需要添加header X-CSRFToken

完整代码如下:

// using jQuery
function getCookie(name) {
    var cookieValue = null;
    if (document.cookie && document.cookie != '') {
        var cookies = document.cookie.split(';');
        for (var i = 0; i < cookies.length; i++) {
            var cookie = jQuery.trim(cookies[i]);
            // Does this cookie string begin with the name we want?
            if (cookie.substring(0, name.length + 1) == (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
}

      function uploadFile() {
        var fd = new FormData();
        fd.append("fileToUpload", document.getElementById('fileToUpload').files[0]);
        var xhr = new XMLHttpRequest();
        var csrftoken = getCookie('csrftoken');
        xhr.upload.addEventListener("progress", uploadProgress, false);
        xhr.addEventListener("load", uploadComplete, false);
        xhr.addEventListener("error", uploadFailed, false);
        xhr.addEventListener("abort", uploadCanceled, false);
        xhr.open("POST", "/wxroot/JS/upload_file");
        xhr.setRequestHeader("X-CSRFToken", csrftoken);
        xhr.send(fd);
      }

总结

但是django这种做法也是在用户的cookie是安全的基础之上,如果用户的cookie被盗取,那么攻击者就不用这么麻烦了,直接就可以获取用户的所有权限,而cookie又是很容易通过js获取的,所以一切的根源在于cookie,只有改变cookie这种机制才能从根源解决这个问题


FAQ

1、使用js提交post请求包含X-CSRFToken时异常InvalidStateError

InvalidStateError: An attempt was made to use an object that is not, or is no longer, usable

InvalidStateError, DOMException code 11

代码调用的方法在当前状态无法调用。通常由 XMLHttpRequest 引起,在方法准备完毕之前调用它会引起错误。

var xhr = new XMLHttpRequest();
xhr.setRequestHeader('Some-Header', 'val');

这时就会出错,因为 setRequestHeader 方法只能在 xhr.open 方法之后调用。

setRequestHeader放到open方法后面问题解决




  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值