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

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

    [复制链接]
发表于 2009-4-24 17:53:56 | 显示全部楼层
弱弱的说一句:

CI不是有url 路由么,或者不用CI的路由,用apache url rewrite就可以避免非法的url了吧.
url rewrite要好一些,不用php参与
 楼主| 发表于 2009-4-24 20:00:38 | 显示全部楼层
弱弱的说一句:

CI不是有url 路由么,或者不用CI的路由,用apache url rewrite就可以避免非法的url了吧.
url rewrite要好一些,不用php参与
bcb51 发表于 2009-4-24 17:53

每个controller->method需要的segment是千变万化的,
这意味着要为每个controller->method编写url rewrite rule,
且每次若有修改segment处理方法,还要顾及更新rewrite rule,
到后期若干条rewrite rule维护起来,相当麻烦
发表于 2009-4-24 20:47:06 | 显示全部楼层
每个controller->method需要的segment是千变万化的,
visvoy 发表于 2009-4-24 20:00


我没看错的话,楼主的seg检查代码貌似只能检查数字吧,而且是简单的大小判断.

假设我认为1-100区间,200-300区间为合法的参数,其余的都不合法,是不是也得修改判断逻辑.

另外,我认为要做到纯粹的OO,你应该在URL类里面应该加一个URL合法检查的函数.

但是,CI好像已经把这事做了,URL router貌似就是这样一个

另外,如果我还想检查是字符串怎么办?比如"book","dress","DVD"?

好办,用正则!
ok,既然用正则,那请问在url router里面写和在楼主写的代码里面写,个人觉得应该是一回事吧,对工作量的减少没多大好处吧.

既然segment是千变万化的,一个正则看来也不能一劳永逸,所以也得看合法的url请求是什么,修改对应的正则.所以也得一个一个对应请求的格式来写正则吧
 楼主| 发表于 2009-4-24 21:20:10 | 显示全部楼层
我没看错的话,楼主的seg检查代码貌似只能检查数字吧,而且是简单的大小判断.

假设我认为1-100区间,200-300区间为合法的参数,其余的都不合法,是不是也得修改判断逻辑.

另外,我认为要做到纯粹的OO,你应该在URL类里 ...
bcb51 发表于 2009-4-24 20:47

明显乃看错了,我的代码是检测seg的“个数”,不是检测具体哪个seg的范围
测试单个seg范围值或是否合法,应该由具体实现的method负责,
前面说了,用url rewrite有缺陷,放大一下就看出来了:
假设你做的project有100以上的method,这些method都需要不同的过滤rule,
那么url rewrite就要写100多条,先不说写完这100多条正则要多久,
日后你要维护某些method,再打开.htaccess,一下子出来100多条正则,看晕不晕
发表于 2009-4-28 09:29:00 | 显示全部楼层

RE: 脆弱的CI缓存系统,1天攻陷你的CI网站

本帖最后由 bcb51 于 2009-4-28 10:27 编辑

好像楼主没明白我的意思.可能是我表达能力很弱的原因,请原谅
明显乃看错了,我的代码是检测seg的“个数”,不是检测具体哪个seg的范围
测试单个seg范围值或是否合法,应该由具体实现的method负责,


我的意思就是只能检查"个数"

前面说了,用url rewrite有缺陷,放大一下就看出来了:
假设你做的project有1 ...


我的意思是假设是seg匹配的内容很复杂,就得用正则.
还有如果真的url rewrite有几百条正则的话,我想楼主的解决方案里面也可能得写同样的几百条正则(其实可以一条正则写完,用 | 来连接关键字 ).原因是我前面写了的,
既然segment是千变万化的,一个正则看来也不能一劳永逸,所以也得看合法的url请求是什么,修改对应的正则.所以也得一个一个对应请求的格式来写正则吧

不是吗?综合一下:实际上那个不是缓存的问题,是URL是否合法的问题,CI当然得缓存合法的url,所以在缓存之前,得由开发者判断请求是否合法,而不是在url认为合法后,再来验证缓存是否合法
发表于 2009-4-28 10:10:57 | 显示全部楼层
我觉得 bcb51 所说的 URL 合法性验证是关键所在。
发表于 2009-4-28 10:46:37 | 显示全部楼层
cache本身没问题,cache不通过uri来检索缓存文件还通过什么来检索?只是在何时启用cache是程序员的事情了。对uri中的segments监控就完全可以预防楼主所说的情况。
这些可以在Controller里面实现,对于能输出同一个页面的uri,那么肯定有一个uri的参数是用最低限度的合法请求参数来请求页面的,就给予它一个允许缓存的权限。
比如楼主说的
这个uri_string允许URI串夹杂垃圾信息,比如:
http://ci-site.com/index.php/index/index/1
http://ci-site.com/index.php/index/index/1/2
http://ci-site.com/index.php/index/index/1/2/3
上面三个请求,CI将生成3个不同的缓存文件

对于出现 segement "1" 之后的参数统统不与缓存, 可以通过检测 segments 的长度来实现。segement "1" 的位置上参数如果超过范围,也不予以缓存,而是直接访问 404 page,可以通过向数据库获取返回数据时判断该参数是否合法。不是在处理uri之前判断,而是在处理完所有流程之后最后判断,这样就不用去管 .htaccess 或者是正则过滤了。

简单说,楼主只是利用了程序员的漏洞,而不是CI的漏洞。

[补充一下]
楼主发现的只是一个cache的实现原理而已,通过 domain+uri 来检索缓存。如果这些uri都是合法的有效请求[对用户而言的有效请求],那么就应该生成这么多缓存,反过来,不是一定要对所有uri都缓存。
通过恶意访问消耗服务器资源不论是通过利用程序员漏洞增加非法缓存,或者是“合法”的并发、恶意请求消耗服务器 cpu 资源或者带宽资源。对服务器造成恶性影响都是必然的,当然可以通过其它层面的手段预防,比如通过 apache 或者 web 服务器的前端代理对同一 ip 的访问频率限制等等,只是这些高效的预防手段已经超出php的范围了。
 楼主| 发表于 2009-4-28 11:59:00 | 显示全部楼层
LS用了麻烦的方法去修补CI的漏洞,每个cache method都写规则? or 配置apache?前面已经说了,给cache method增加长度or合理性判断不是明智的做法,会造成紧耦合。

我已发布了修正CI缓存漏洞的代码,在前面某页,基于扩展,不修改CI源码,不用重写缓存method,不用配置 apache 。

关于CI缓存,这就是漏洞,手册上对于Cache可能产生垃圾文件的事情只字未提,反而却说CI的缓存如何如何方便,没看过CI源码的程序员很容易写出漏洞project。

你不能要求每个用CI的人,都看一遍CI源码,大部分人都是拿过来“用”,不是“看”
发表于 2009-4-28 12:27:48 | 显示全部楼层
对于楼主的钻研精神我表示钦佩。

不过,对于楼主一直说此问题是漏洞,我不敢苟同。

缓存和 URL 是否合法是两个层面的问题,缓存本身并不能判断 URL 是否合法,需要另一套机制来保证,不管他是扩展核心,还是每个控制器自己实现,都是另一个层面的问题。
 楼主| 发表于 2009-4-28 18:43:24 | 显示全部楼层
本帖最后由 visvoy 于 2009-4-28 18:57 编辑

Hex的意思换句话讲,就是不能直接使用CI的缓存,必须替代or扩展才行,乃自己潜意识里都承认这是漏洞了

关于这个漏洞,前面已经有人中招,你说是程序员自己的问题?归根究底还是CI缓存判断有缺陷

一个网站因为某个缺陷被攻击,请问这个“缺陷”常规应该叫什么?随便个人都知道:这叫漏洞

举个简单的例子:SQL有注入漏洞,我们怎么办?每条SQL都加addslashes()?累不累啊,你?即使编程再牛X,人无完人,你早晚会忘记一次addslashes(),使网站留下漏洞,这点不能反驳。再说句废话:解决SQL注入当然是从系统接口杜绝SQL注入,CI这么做了,CI从接口级别杜绝了漏洞,于是大家用ar写SQL都不用担心漏洞了,method/model怎么写都行,无需手工控制addslashes()

将这个例子主角换成CI缓存呢?CI存在生成垃圾缓存文件的漏洞,怎么办?每个method都加seg长度判断?累不累啊,你?即使编程牛X,人无完人,你早晚会忘记一次seg长度判断,使网站留下漏洞,这点不能反驳。解决方法当然是从系统接口杜绝生成垃圾文件,CI没这么做,CI没有从接口级别杜绝缓存漏洞,于是大家用CI缓存都有顾虑了,每个缓存method/model都要手工判断seg长度

CI是方便,但客观上说,她的确存在缓存漏洞,看问题应该以大众角度看,不是以资深CIer来看

本版积分规则