当前位置:Gxlcms >
数据库问题 >
ThinkPHP 3.1,3.2中对IN和BETWEEN正则匹配不当导致的一个SQLi
ThinkPHP 3.1,3.2中对IN和BETWEEN正则匹配不当导致的一个SQLi
时间:2021-07-01 10:21:17
帮助过:35人阅读
// where子单元分析
2 protected function parseWhereItem(
$key,
$val) {
3 $whereStr = ‘‘
;
4 if(
is_array(
$val)) {
5 if(
is_string(
$val[0
])) {
6 if(
preg_match(‘/^(EQ|NEQ|GT|EGT|LT|ELT)$/i‘,
$val[0])) {
// 比较运算
7 $whereStr .=
$key.‘ ‘.
$this->comparison[
strtolower(
$val[0])].‘ ‘.
$this->parseValue(
$val[1
]);
8 }
elseif(
preg_match(‘/^(NOTLIKE|LIKE)$/i‘,
$val[0])){
// 模糊查找
9 if(
is_array(
$val[1
])) {
10 $likeLogic =
isset(
$val[2])?
strtoupper(
$val[2]):‘OR‘
;
11 if(
in_array(
$likeLogic,
array(‘AND‘,‘OR‘,‘XOR‘
))){
12 $likeStr =
$this->comparison[
strtolower(
$val[0
])];
13 $like =
array();
14 foreach (
$val[1]
as $item){
15 $like[] =
$key.‘ ‘.
$likeStr.‘ ‘.
$this->parseValue(
$item);
16 }
17 $whereStr .= ‘(‘.
implode(‘ ‘.
$likeLogic.‘ ‘,
$like).‘)‘
;
18 }
19 }
else{
20 $whereStr .=
$key.‘ ‘.
$this->comparison[
strtolower(
$val[0])].‘ ‘.
$this->parseValue(
$val[1
]);
21 }
22 }
elseif(‘exp‘==
strtolower(
$val[0])){
// 使用表达式
23 $whereStr .= ‘ (‘.
$key.‘ ‘.
$val[1].‘) ‘
;
24 }
elseif(
preg_match(‘/IN/i‘,
$val[0])){
// IN 运算
25 if(
isset(
$val[2]) && ‘exp‘==
$val[2
]) {
26 $whereStr .=
$key.‘ ‘.
strtoupper(
$val[0]).‘ ‘.
$val[1
];
27 }
else{
28 if(
is_string(
$val[1
])) {
29 $val[1] =
explode(‘,‘,
$val[1
]);
30 }
31 $zone =
implode(‘,‘,
$this->parseValue(
$val[1
]));
32 $whereStr .=
$key.‘ ‘.
strtoupper(
$val[0]).‘ (‘.
$zone.‘)‘
;
33 }
34 }
elseif(
preg_match(‘/BETWEEN/i‘,
$val[0])){
// BETWEEN运算
35 $data =
is_string(
$val[1])?
explode(‘,‘,
$val[1]):
$val[1
];
36 $whereStr .= ‘ (‘.
$key.‘ ‘.
strtoupper(
$val[0]).‘ ‘.
$this->parseValue(
$data[0]).‘ AND ‘.
$this->parseValue(
$data[1]).‘ )‘
;
37 }
else{
38 throw_exception(L(‘_EXPRESS_ERROR_‘).‘:‘.
$val[0
]);
39 }
40 }
else {
41 $count =
count(
$val);
42 $rule =
isset(
$val[
$count-1])?
strtoupper(
$val[
$count-1]):‘‘
;
43 if(
in_array(
$rule,
array(‘AND‘,‘OR‘,‘XOR‘
))) {
44 $count =
$count -1
;
45 }
else{
46 $rule = ‘AND‘
;
47 }
48 for(
$i=0;
$i<
$count;
$i++
) {
49 $data =
is_array(
$val[
$i])?
$val[
$i][1]:
$val[
$i];
50 if(‘exp‘==
strtolower(
$val[
$i][0
])) {
51 $whereStr .= ‘(‘.
$key.‘ ‘.
$data.‘) ‘.
$rule.‘ ‘
;
52 }
else{
53 $op =
is_array(
$val[
$i])?
$this->comparison[
strtolower(
$val[
$i][0])]:‘=‘
;
54 $whereStr .= ‘(‘.
$key.‘ ‘.
$op.‘ ‘.
$this->parseValue(
$data).‘) ‘.
$rule.‘ ‘
;
55 }
56 }
57 $whereStr =
substr(
$whereStr,0,-4
);
58 }
59 }
else {
60 //对字符串类型字段采用模糊匹配
61 if(C(‘DB_LIKE_FIELDS‘) &&
preg_match(‘/(‘.C(‘DB_LIKE_FIELDS‘).‘)/i‘,
$key)) {
62 $val = ‘%‘.
$val.‘%‘
;
63 $whereStr .=
$key.‘ LIKE ‘.
$this->parseValue(
$val);
64 }
else {
65 $whereStr .=
$key.‘ = ‘.
$this->parseValue(
$val);
66 }
67 }
68 return $whereStr;
69 }
第24行的preg_match(‘/IN/i‘,$val[0])
第34行的preg_match(‘/BETWEEN/i‘,$val[0])
两个正则表达式没有设置起始,因此xxxinxxxx,xxxbetweenxxx的字符串都可以匹配成功,因而构成了注入。
ThinkPHP 3.1,3.2中对IN和BETWEEN正则匹配不当导致的一个SQLi
标签:xor rest thinkphp sse throw xxx 成功 pre logic