• ThinkPHP 3.1,3.2中对IN和BETWEEN正则匹配不当导致的一个SQLi


     1     // 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的字符串都可以匹配成功,因而构成了注入。

  • 相关阅读:
    关于多态的一些问题
    003 关于shell基础,大数据的前期准备
    002 在大数据中基础的llinux基本命令
    013 MapReduce八股文的wordcount应用
    接口里语句的修饰问题
    Apache Rewrite url重定向功能的简单配置
    学习笔记 --- 缓存、动态页面静态化、网站优化
    使用PHP连接、操纵Memcached的原理和教程
    Apache中关于页面缓存的设置
    缓存(之一) 使用Apache Httpd实现http缓存
  • 原文地址:https://www.cnblogs.com/ingd/p/7222502.html
Copyright © 2020-2023  润新知