2 Q. b, T$ D/ g% C4 ]% P 或者) J# s% y) E# S5 a
$Model->where("id=%d and username='%s' and xx='%f'",$id,$username,$xx)->select(); , {! v$ M* y2 { 4 t- I9 ^% b) q0 x( }# f 但是,当你使用如下代码时,却没有”防止SQL注入”效果(而官方文档却说可以防止SQL注入):; }0 S# O' V' x" t
$model->query('select * from user where id=%d and status=%s',$id,$status);: ?! m0 g* s* r6 m$ o1 }. b
- n5 y( O# }% R或者) W/ p$ T! p" m9 g3 q( R" w, Q
$model->query('select * from user where id=%d and status=%s',array($id,$status)); # Z1 B* ?0 B7 G" A" }+ l ! e) G: K% O3 Q/ K9 k& ], f3 X 原因: 8 J" U. D% X$ ]9 I+ D. n% ?9 kThinkPHP/Lib/Core/Model.class.php 文件里的parseSql函数没有实现SQL过滤.- ?7 u1 W% S# l. K2 [! \0 v
原函数:5 X$ F& }) `* X) }
protected function parseSql($sql,$parse) { % O0 j9 D7 o8 a: q3 e; }& K // 分析表达式, W# F& w5 ~! G0 t, Q, ^/ e
if(true === $parse) { " \, D& v& ~6 @9 [: G/ ^4 F% p $options = $this->_parseOptions();- I P3 Q% z) _1 t: y
$sql = $this->db->parseSql($sql,$options);4 ?) ?: ~# z4 `" w$ m* C4 K
}elseif(is_array($parse)){ // SQL预处理 " Y' e, \, i# n0 l4 c $sql = vsprintf($sql,$parse); + k( e: n: k" ? n# ?) C% ^ }else{- U7 @8 _ t K, O2 i# l" S
$sql = strtr($sql,array('__TABLE__'=>$this->getTableName(),'__PREFIX__'=>C('DB_PREFIX'))); & t9 [. c* S$ M6 J/ C4 x4 ^ } / Y% x( p, \& B! O9 f/ g $this->db->setModel($this->name); ) ?- [; f! j4 i z6 ]# z return $sql; - p f1 x+ S/ w5 U# S! G0 \7 h }. K4 K9 O5 G7 R
. B0 D4 d; o. l/ J. j8 Y, c% ^, c验证漏洞(举例): & T& u3 q+ G: m3 w0 M1 Q. l* k请求地址: $ j, v$ x- k7 n) q$ P8 Phttp://localhost/Main?id=boo” or 1=”1 ! c1 X! `- R9 |2 f/ z3 M或/ i7 T$ g6 C# I5 Z
http://localhost/Main?id=boo%22%20or%201=%221 & h6 ?* p$ v. t* m: Gaction代码:/ ^0 {$ Z* c3 g' N
$model=M('Peipeidui'); / g5 ?/ G) D6 `- [ $m=$model->query('select * from peipeidui where name="%s"',$_GET['id']);+ O2 M h* e" t7 ?7 y2 `
dump($m);exit;1 `* `1 Y" @7 l: X
或者$ ?2 k( F! n$ I9 m
$model=M('Peipeidui'); 9 X8 @, H8 ^! {6 }2 g- p $m=$model->query('select * from peipeidui where name="%s"',array($_GET['id'])); % _ i5 f) K: t3 ]: L1 s dump($m);exit;" O- x9 e" p& B7 I" d# h
结果:& W2 X, |7 D. w9 D' U3 P; B$ w; l, C
表peipeidui所有数据被列出,SQL注入语句起效., ~4 W2 R u$ C* R2 K N
解决办法:$ t. @9 u U4 n+ m, [
将parseSql函数修改为:' n' u3 b5 ]% X# B: }6 N8 l' ]$ @
protected function parseSql($sql,$parse) {1 ^$ X- T8 y3 `/ e5 B
// 分析表达式 . n& @+ O2 D8 s* ^: i5 j; X& S. E if(true === $parse) { 2 V$ a9 M f1 ?- ?3 V( @ M $options = $this->_parseOptions();3 ]: F0 F, _% l8 g9 t
$sql = $this->db->parseSql($sql,$options); ; O3 O4 |2 X3 k0 j: X. z }elseif(is_array($parse)){ // SQL预处理 5 P6 D" m3 O2 _6 V8 I: T: B $parse = array_map(array($this->db,'escapeString'),$parse);//此行为新增代码 - Q! L" O1 X. x. a9 X+ P6 X/ b $sql = vsprintf($sql,$parse);0 t/ }! ?2 f w* K( L5 E) o, t
}else{0 M( B, c( T t# i# R* M3 h" v/ n* e
$sql = strtr($sql,array('__TABLE__'=>$this->getTableName(),'__PREFIX__'=>C('DB_PREFIX'))); $ Y9 Y1 V9 ?, q } 6 G7 I5 Q3 n2 I2 { $this->db->setModel($this->name); d2 T# Q W0 C- m
return $sql; b5 ]3 u; m. S# Y } ( P: _- F- \, E6 F4 N% M J/ A 5 S- Z3 j* R' `7 k& P) _总结: 8 E! e+ ]$ K! E5 @7 d不要过分依赖TP的底层SQL过滤,程序员要做好安全检查 % |1 M1 n9 N, W不建议直接用$_GET,$_POST 6 e9 U i; M7 n[/td][/tr] ) l3 M3 O$ e+ a0 g3 @4 J) m0 o[/table]+1 # x2 ]. x: @& c6 I- S% Q% V5 J% t9 }! k9 F4 d& i
! d* c( Q5 K( s, e3 o4 [# V