cuimuxi
发表于 2009-4-6 18:52:24
补充一下,我说的controller和method都不是CI框架中的原始controller和method,而是自己写的控制器和方法,也就是自己手工认证
Hex
发表于 2009-4-6 23:48:48
我理解 cuimuxi 朋友的意思,在控制器方法中验证,如果不符合要求就不要执行
$this->output->cache(n);
这样就不会在这次非法访问中生成缓存。
visvoy
发表于 2009-4-7 06:53:01
楼主为什么总是误会我的意思呢,难道我的表达能力就这么差
我没说让CI去干认证参数这档子事,难道就不能在controller的method中加一条小小的数据有效性认证么?
我也没说404能管得了缓存,生成缓存的文件就让它缓 ...
cuimuxi 发表于 2009-4-6 18:50 http://codeigniter.org.cn/forums/images/common/back.gif
其实看明白了,你还是停留在说的阶段,
“在controller的method中加一条小小的数据有效性认证”
说起来是很容易,你有没有想过一个project每个method的segment验证是千变万化的?
“一条小小的验证”在一个project里面会变成“几十几百条小小的验证”
就拿我正在写的交友系统,粗略算一下带缓存的method少说也近百了,
如果给每个method增加小小的验证,那程序将耦合到囧rz的地步,
假如下个CI版本变更了segment相关代码,怎么办?
挨个修改你说的“几十几百个小小的验证”吗?
CI没有考虑到segment验证是她的缺失,但既然提供了cache功能,
其附带了一个极有可能被攻击的缺失,我认为这就是漏洞,
毫不知情的开发者一旦用了CI的cache,那就等于任人鱼肉,
随便几个人一起攻击,1两天服务器就挂了,这还不叫漏洞?
你可以说你为每个method加验证,可是你终究会有疏忽的时候,而那时候你就要为CI的缺失买单了
visvoy
发表于 2009-4-7 07:11:44
补充一下,我说的controller和method都不是CI框架中的原始controller和method,而是自己写的控制器和方法,也就是自己手工认证
cuimuxi 发表于 2009-4-6 18:52 http://codeigniter.org.cn/forums/images/common/back.gif
搞了半天白搞了,前面的发言完全没有意义了
1. 你的不认为这是严重漏洞,是建立在自己修复过漏洞的CI框架,不是原生的CI框架
2. 你自己都承认了CI缓存漏洞,承认了其危害性,不然干嘛手工认证“有效性”?
3. 你说的“有效性”如果包括segment_array()长度有效性,那就确认了第2点
4. 任何人都可以轻松搞垮服务器的漏洞,如果不算严重漏洞,那这世界上就没有严重漏洞了
Hex
发表于 2009-4-7 11:15:01
那楼主觉得应该怎么验证有效性呢?希望能提出有建设性的思路或者是代码。
我觉得缓存有效性验证没有统一的模式,无法完全由框架“自动”提供。
BillyFan
发表于 2009-4-7 21:37:30
本帖最后由 BillyFan 于 2009-4-7 21:53 编辑
说起来是很容易,你有没有想过一个project每个method的segment验证是千变万化的?
“一条小小的验证”在一个project里面会变成“几十几百条小小的验证”
就拿我正在写的交友系统,粗略算一下带缓存的method少说也近百了,
如果给每个method增加小小的验证,那程序将耦合到囧rz的地步,
个人认为,就因为每个method里需要的验证都是不同的,因此framework本身是不可能提供一个万能的验证功能的。
同时,作为程序员,有义务和责任对自己写的程序进行安全验证,
举例来说,如果我在noticeboard这个controller里有如下一个method,
function readpost($pid){
$query = $this->db->get_where('posts',array('post_id' => $pid));
$rowPost = $query->row();
$data['content'] = $rowPost->title;
$this->output->cache(10);
$this->load->view('readpost',$data);
}
那么我想我有必要在这个method里增加一个验证,如果请求的$pid不存在的,应该给用户返回一个错误信息,于是乎,我就可以把method修改成下面这个样子:
function readpost($pid){
$query = $this->db->get_where('posts',array('post_id' => $pid));
if($query->num_rows() == 1)
$rowPost = $query->row();
$data['content'] = $rowPost->title;
$this->output->cache(10);
$this->load->view('readpost',$data);
}
else{
// go to 404;
}
}
这样,假设我的数据表post里只有id=1和id=2两条记录,
那么当用户请求:http://testdomain.com/noticeboard/readpost/3
的时候,就会返回404,而不生成缓存
BillyFan
发表于 2009-4-7 21:54:27
lz是否认为,在上面我的那个例子里,我加的那段验证是应该由CI自动完成,而不是我们程序员自己手动添加呢?
以我看来,在每一个这类应用中,这样的验证都应该由我们程序员来手动添加,而不能依靠CI,也无法依靠CI,
对于上面那个例子来说,如果是在加入验证之前的代码,当用户访问http://testdomain.com/noticeboard/readpost/3 的时候,由于post3根本不存在,那么$query->num_rows()就是0,而$query->row()的结果就不是一个object,$data['content'] = $rowPost->title;就会出错,这样的代码,恐怕在任何一个framework里都是报错吧?
无论是否有缓存,我们都需要在这里加一个有效性的验证,那就不存在为了缓存而额外加有效性验证的问题,
另外,lz提到
如果给每个method增加小小的验证,那程序将耦合到囧rz的地步,
我上面那个例子里,加了验证,没有增加耦合吧?
对于
你可以说你为每个method加验证,可是你终究会有疏忽的时候,而那时候你就要为CI的缺失买单了
这个。。。。。既然我们没有忘记加“$this->output->cache(10);”,为什么会忘记加验证呢?这个是我们自己的疏忽,不能怪CI吧,呵呵。
BillyFan
发表于 2009-4-7 22:07:42
当然,不可否认CI的这个缓存有点弱,
不知道是我没找到,还是CI的缓存就只有$this->output->cache(n);这么一个语句。
我发现,CI生成缓存文件的名字,就是简单的把用户请求的URL给md5一下,而不是由程序员自己来决定缓存的名字,
这样带来的不良结果是什么呢,还请看我前面那个例子,在我加了验证之后的代码:
function readpost($pid){
$query = $this->db->get_where('posts',array('post_id' => $pid));
if($query->num_rows() == 1)
$rowPost = $query->row();
$data['content'] = $rowPost->title;
$this->output->cache(10);
$this->load->view('readpost',$data);
}
else{
// go to 404;
}
}
当用户请求http://testdomain.com/noticeboard/readpost/3 的时候,不生成缓存,
请求http://testdomain.com/noticeboard/readpost/1 的时候,就生成缓存,
看起来已经解决了缓存攻击的问题,
实际上呢,
如果我们请求一下
http://testdomain.com/noticeboard/readpost/1/2。。。。
omg,又一个缓存
再来,
http://testdomain.com/noticeboard/readpost/1/2/3。。。。
又一个缓存
只要第一个参数有效了,验证就通过,缓存就出现。。。。。
咋儿办?
我目前使用的解决方法是,读一个额外的参数:
function readpost($pid,$url_extra = false){
$query = $this->db->get_where('posts',array('post_id' => $pid));
if($query->num_rows() == 1)
$rowPost = $query->row();
$data['content'] = $rowPost->title;
if($url_extra === false){
$this->output->cache(10);
}
$this->load->view('readpost',$data);
}
else{
// go to 404;
}
}
貌似很土很麻烦,每一个生成缓存的function里都要多增加一个额外的参数,
我还没想到其他的方法,希望有大侠能研究看看有没有更好的方法
visvoy
发表于 2009-4-8 06:59:13
个人认为,就因为每个method里需要的验证都是不同的,因此framework本身是不可能提供一个万能的验证功能的。
同时,作为程序员,有义务和责任对自己写的程序进行安全验证,
举例来说,如果我在noticeboard这个co ...
BillyFan 发表于 2009-4-7 21:37
如果你没有自己修补过CI缓存的话,你的这个method明显存在漏洞,
如何攻击?只要这样,循环访问:
http://testdomain.com/noticeboard/readpost/2/1
到
http://testdomain.com/noticeboard/readpost/2/10000000
就会生成一千万个垃圾缓存
你写的method没有任何防御措施,也不会显示404
因为确定了$pid=2是合法的,但后面的/1~/10000000却没有检测,
写缓存的时候CI仍然会把/1~/10000000一起md5,生成1千万个垃圾缓存
visvoy
发表于 2009-4-8 07:04:48
当然,不可否认CI的这个缓存有点弱,
不知道是我没找到,还是CI的缓存就只有$this->output->cache(n);这么一个语句。
我发现,CI生成缓存文件的名字,就是简单的把用户请求的URL给md5一下,而不是由程序员自己来决定 ...
BillyFan 发表于 2009-4-7 22:07 http://codeigniter.org.cn/forums/images/common/back.gif
这个方法不好,这样会加重编程的负担,每个cache method都添加$extra===false的话,会造成紧耦合,不利于后期维护和再开发
目前比较有效且是松耦合的解决办法是扩展CI_URI和CI_Output,
我在前面已经提过思路,实现也很简单。
乃们包括斑竹都不愿意自己写代码哦?嘿嘿,那我整理一下发上来吧
页:
1
2
3
4
[5]
6
7
8
9
10
11
12