找回密码
 立即注册
欢迎中测联盟老会员回家,1997年注册的域名
查看: 2199|回复: 0
打印 上一主题 下一主题

ThinkPHP框架通杀所有版本的一个SQL注入漏洞

[复制链接]
跳转到指定楼层
楼主
发表于 2013-7-27 18:30:26 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
下面是摘自thinkphp官方的一个公告,官方直接贴出这些东西是非常不负责的行为,跟上次apache公开的Struts2的代码执行一样的行为,会造成很多用户被黑。建议类似的厂商不要再做这种蠢事。
7 Q! K+ v* [7 xThinkPHP 3.1.3及之前的版本存在一个SQL注入漏洞,漏洞存在于ThinkPHP/Lib/Core/Model.class.php 文件
/ W' a) Y+ W% ^$ F* [/ E6 H- V根据官方文档对”防止SQL注入”的方法解释(见http://doc.thinkphp.cn/manual/sql_injection.html)
0 w$ F7 L8 e1 U使用查询条件预处理可以防止SQL注入,没错,当使用如下代码时可以起到效果:
/ C. u3 m0 k& d  f% q% p$Model->where("id=%d and username='%s' and xx='%f'",array($id,$username,$xx))->select();
8 @& C0 V, d3 j" D+ m+ S2 n
! H2 V2 ~+ v5 c" O 或者
5 e; Z5 J4 \: u$Model->where("id=%d and username='%s' and xx='%f'",$id,$username,$xx)->select();1 `/ w1 F) X3 Z  x. \+ V* y3 B

( D6 r+ U% |( J2 u7 q3 Y 但是,当你使用如下代码时,却没有”防止SQL注入”效果(而官方文档却说可以防止SQL注入):  F# c  Z  ~* Y) \( ?, f2 p* [
$model->query('select * from user where id=%d and status=%s',$id,$status);3 Z" g9 |. k5 v. C0 C* i/ E
1 n  m- P: j% m0 k, q
或者  k; ]8 t: q8 J- K
$model->query('select * from user where id=%d and status=%s',array($id,$status));
1 ~% ~- g& ^0 @, Y, d1 T4 `5 W/ E/ \/ \+ o/ i  |8 W
原因:, B9 G- P- q2 K2 ]9 H& p
ThinkPHP/Lib/Core/Model.class.php 文件里的parseSql函数没有实现SQL过滤.; b1 S+ x  A% S1 \
原函数:
" }- P. x' ]9 a$ G% }4 j1 Nprotected function parseSql($sql,$parse) {5 G$ o# {2 K) r, x8 _
        // 分析表达式4 a' [: z# K8 C
        if(true === $parse) {. i2 w% a) {6 ^/ ~1 r- B# |
            $options =  $this->_parseOptions();
6 O  Y* Q* v5 w5 m; l. u            $sql  =   $this->db->parseSql($sql,$options);
( H% z3 }. y- N; R5 `        }elseif(is_array($parse)){ // SQL预处理: i2 V( p* x% Z: a$ K9 T
            $sql  = vsprintf($sql,$parse);3 w5 ~* e; H0 C4 X! `
        }else{4 a, b+ d9 E7 w+ Y/ N
            $sql    =   strtr($sql,array('__TABLE__'=>$this->getTableName(),'__PREFIX__'=>C('DB_PREFIX')));
0 B0 o/ x2 y, Z$ G        }
$ w8 f# S2 A. ~! Z/ _: n        $this->db->setModel($this->name);
; M3 D0 y* d% E; N& ?9 |        return $sql;' w0 G( J: C' I: d9 e
    }7 n- ?( Z5 r4 l; G: R
- t# s3 M0 ^/ i) y2 ^! ?4 Q
验证漏洞(举例):
9 l0 X: M0 I0 p请求地址:
& M. H/ e- E2 k& _5 Uhttp://localhost/Main?id=boo” or 1=”1, v; A2 T: w" O# W

  F/ v6 z: T: |1 qhttp://localhost/Main?id=boo%22%20or%201=%2213 L% p7 Q4 j* z. t: V$ z2 q: I
action代码:
1 E  B5 ^+ A- G/ x, A! Q2 W; D( V$model=M('Peipeidui');
4 W) h* o( g) X3 m        $m=$model->query('select * from peipeidui where name="%s"',$_GET['id']);4 ?/ m' U* ]# G1 f) Z' h
        dump($m);exit;3 K1 r8 J; g- B" C! d' T5 I# w, D
或者" [, j- F2 S( y: y; ]
$model=M('Peipeidui');
, p$ s3 t) \+ |: H8 A' Z  r' ~        $m=$model->query('select * from peipeidui where name="%s"',array($_GET['id']));
1 X9 M! ]8 |( e# }        dump($m);exit;
0 p0 l# A) ^6 X: q/ ^( o/ L, Q! y结果:% E4 D, H; ?/ L
表peipeidui所有数据被列出,SQL注入语句起效.! {* q* U. i0 o. e3 j
解决办法:3 O1 g/ x, ^4 P
将parseSql函数修改为:2 O: o: @! k" V  u& t  L. {
protected function parseSql($sql,$parse) {" B! n, X- a) }& r& E
        // 分析表达式
2 S$ Q# G& Y* y+ b. n. {        if(true === $parse) {
* O7 r8 I; b0 Y8 V& v) }" p            $options =  $this->_parseOptions();) }0 n% S: c9 t  X. F
            $sql  =   $this->db->parseSql($sql,$options);7 t& g8 P/ C# y* v& Y
        }elseif(is_array($parse)){ // SQL预处理/ e9 V: C5 y9 Z
            $parse = array_map(array($this->db,'escapeString'),$parse);//此行为新增代码, P; b) ]' e6 c) G+ ^/ I* M
            $sql  = vsprintf($sql,$parse);
. O0 H! _+ H/ L0 O1 `1 w        }else{3 [8 A) v- R, T3 n
            $sql    =   strtr($sql,array('__TABLE__'=>$this->getTableName(),'__PREFIX__'=>C('DB_PREFIX')));
2 t3 L6 ~; d9 P3 d% x        }
7 F) L- y, E) _+ L$ r        $this->db->setModel($this->name);
. R- l  U3 ]3 K3 }( a        return $sql;
+ o7 W- m, f6 D6 Q7 I, y: ]( v    }
/ C$ P! l; y. O: h
. ?7 [- i3 y- O4 o. V总结:
  }  P5 y3 I7 b* [不要过分依赖TP的底层SQL过滤,程序员要做好安全检查
" k, a" G" q4 \6 K' a不建议直接用$_GET,$_POST
. t/ l1 v0 Y0 Q. N: r3 {8 q[/td][/tr]* ~8 }( s; H% }  }) Q
[/table]+11 q5 x  T' ^- z6 [( j
" b+ _) ^& g7 s& ]; d1 i7 N

; u+ [$ v: _4 g" @
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表