用户
 找回密码
 入住 CI 中国社区
搜索
楼主: visvoy
收起左侧

[讨论/交流] 脆弱的CI缓存系统,1天攻陷你的CI网站

    [复制链接]
发表于 2009-4-8 07:35:11 | 显示全部楼层
呵呵,楼主既然有好的想法和代码就要分享哦!
 楼主| 发表于 2009-4-8 07:38:31 | 显示全部楼层
本帖最后由 visvoy 于 2009-4-8 08:47 编辑
我上面那个例子里,加了验证,没有增加耦合吧?

这个。。。。。既然我们没有忘记加“$this->output->cache(10);”,为什么会忘记加验证呢?这个是我们自己的疏忽,不能怪CI吧,呵呵。
BillyFan 发表于 2009-4-7 21:54

1. 谈耦合是放在project里面,单个method或几个method的project耦不耦没虾米讨论价值
2. 46L的例子根本防不住cache漏洞,谈耦合没意义
3. 48L的例子放大一下看:
如果这是一个project的method,而project很可能需要readpost/1/2/3
三个uri segment,其中/2和/3不一定是数据库查询参数,按你的思路,
必须在检测能否cache的时候加入/2和/3检测,
再放大一点:倘若/2是个区域合理性参数,要再次变更cache相关的if判断
再再放大一点:几十几百method可能都要修改/2/3的cache检测,还有部分/2的区域性判断
最后到project:除了必要修改(老板要求的),你每次还要花费时间去修改几十几百个cache合理性判断

因为你的缓存接口依赖于每个缓存的实现,违反了依赖倒转原理,也就是说耦合了

那么,解释第二条引用就方便了,你每次要额外修改缓存判断代码,这肯定增加了工作量,且是无意义的工作量(本来可以修改接口避免的),于是隐性出错几率会相应增加(某段代码可能写了几个月之后再来修改,你能完全记住吗?何况还可能是你修改他人的代码)
 楼主| 发表于 2009-4-8 07:45:05 | 显示全部楼层
呵呵,楼主既然有好的想法和代码就要分享哦!
Hex 发表于 2009-4-8 07:35

kaokao,原来斑竹一职潜水哇,等着,我还要从项目里面抽代码出来。。。。。。。
 楼主| 发表于 2009-4-8 07:57:08 | 显示全部楼层
解决办法:
1. 先扩展URI类
PHP复制代码
class MY_URI extends CI_URI
{
// 记录被调用过的最大 segment 序号,默认=2 (1=Controller, 2=action)
var $_goodseg = 2;
 
// HOOK: 记录曾经使用过的 segment 的最大序号,用来过滤垃圾 seg
function segment($n, $no_result = FALSE)
{
  if ($n > $this->_goodseg)
  {
   $this->_goodseg = $n;
  }
  return parent::segment($n, $no_result);
}
 
// EXTEND: 只获取曾经被 ::segment() 方法调用过的最大序号之内的 segment 数组集合
function good_rsegment_array()
{
   return array_slice($this->rsegments, 0, $this->_goodseg);
}
} // END class MY_URI
复制代码


2. 再扩展OUTPUT类
PHP复制代码
class MY_Output extends CI_Output
{
// HOOK: 防止写垃圾缓存
function _write_cache($output)
{
  $CI = &get_instance();
  $t = $CI->uri->uri_string;
  $CI->uri->uri_string = implode('/', $CI->uri->good_rsegment_array());
  if ('/' == substr($t, 0, 1))
  {
   $CI->uri->uri_string = '/'.$CI->uri->uri_string;
  }
  parent::_write_cache($output);
  // 恢复 uri string ,以供其他物件调用
  $CI->uri->uri_string = $t;
}
} // END class MY_Output
复制代码


3. 带缓存的method要用$this->uri->segment(n)来获取uri参数

这样就在接口限制了生成垃圾缓存,而对于缓存实现,不用添加任何缓存判断代码

评分

参与人数 2威望 +6 收起 理由
chzuping + 1
Hex + 5 原创内容

查看全部评分

 楼主| 发表于 2009-4-8 08:01:47 | 显示全部楼层
本来想等山姆大叔的更新,既然有人要求,就发出来了
发表于 2009-4-8 13:38:25 | 显示全部楼层
感谢 visvoy 分享他的代码!加分!
发表于 2009-4-9 08:42:54 | 显示全部楼层
听楼主这么一分析,的确存在这个弊端,看来还是使用其他的缓存
发表于 2009-4-9 15:09:25 | 显示全部楼层
非常感谢分享。
发表于 2009-4-9 22:08:19 | 显示全部楼层
用Kohana吧,还可以按tag缓存,自动垃圾收集,可选4,5种方式缓存
发表于 2009-4-10 15:44:50 | 显示全部楼层
没想到啊~!

本版积分规则