2009-07-04 18:41
function
CheckSql(
$db_string
,
$querytype
=
'
select
'
) 2 { 3 global $cfg_cookie_encode ; 4 $clean = '' ; 5 $error = '' ; 6 $old_pos = 0 ; 7 $pos = - 1 ; 8 $log_file = DEDEINC . ' /../data/ ' . md5 ( $cfg_cookie_encode ) . ' _safe.txt ' ; 9 $userIP = GetIP(); 10 $getUrl = GetCurUrl(); 11 12 // 如果是普通查询语句,直接过滤一些特殊语法 13 if ( $querytype == ' select ' ) 14 { 15 $notallow1 = " [^0-9a-z@/._-]{1,}(union|sleep|benchmark|load_file|outfile)[^0-9a-z@/.-]{1,} " ; 16 17 // $notallow2 = "--|//*"; 18 if ( eregi ( $notallow1 , $db_string )) 19 { 20 fputs ( fopen ( $log_file , ' a+ ' ) , " $userIP || $getUrl || $db_string ||SelectBreak/r/n " ); 21 exit ( " <font size='5' color='red'>Safe Alert: Request Error step 1 !</font> " ); 22 } 23 } 24 25 // 完整的SQL检查 26 while ( true ) 27 { 28 $pos = strpos ( $db_string , ' / '' , $pos + 1); 29 if ($pos === false) 30 { 31 break; 32 } 33 $clean .= substr($db_string, $old_pos, $pos - $old_pos); 34 while (true) 35 { 36 $pos1 = strpos($db_string, ' / '' , $pos + 1 ); 37 $pos2 = strpos ( $db_string , ' // ' , $pos + 1 ); 38 if ( $pos1 === false ) 39 { 40 break ; 41 } 42 elseif ( $pos2 == false || $pos2 > $pos1 ) 43 { 44 $pos = $pos1 ; 45 break ; 46 } 47 $pos = $pos2 + 1 ; 48 } 49 $clean .= ' $s$ ' ; 50 $old_pos = $pos + 1 ; 51 } 52 $clean .= substr ( $db_string , $old_pos ); 53 $clean = trim ( strtolower ( preg_replace ( array ( ' ~/s+~s ' ) , array ( ' ' ) , $clean ))); 54 55 // 老版本的Mysql并不支持union,常用的程序里也不使用union,但是一些黑客使用它,所以检查它 56 if ( strpos ( $clean , ' union ' ) !== false && preg_match ( ' ~(^|[^a-z])union($|[^[a-z])~s ' , $clean ) != 0 ) 57 { 58 $fail = true ; 59 $error = " union detect " ; 60 } 61 62 // 发布版本的程序可能比较少包括--,#这样的注释,但是黑客经常使用它们 63 elseif ( strpos ( $clean , ' /* ' ) > 2 || strpos ( $clean , ' -- ' ) !== false || strpos ( $clean , ' # ' ) !== false ) 64 { 65 $fail = true ; 66 $error = " comment detect " ; 67 } 68 69 // 这些函数不会被使用,但是黑客会用它来操作文件,down掉数据库 70 elseif ( strpos ( $clean , ' sleep ' ) !== false && preg_match ( ' ~(^|[^a-z])sleep($|[^[a-z])~s ' , $clean ) != 0 ) 71 { 72 $fail = true ; 73 $error = " slown down detect " ; 74 } 75 elseif ( strpos ( $clean , ' benchmark ' ) !== false && preg_match ( ' ~(^|[^a-z])benchmark($|[^[a-z])~s ' , $clean ) != 0 ) 76 { 77 $fail = true ; 78 $error = " slown down detect " ; 79 } 80 elseif ( strpos ( $clean , ' load_file ' ) !== false && preg_match ( ' ~(^|[^a-z])load_file($|[^[a-z])~s ' , $clean ) != 0 ) 81 { 82 $fail = true ; 83 $error = " file fun detect " ; 84 } 85 elseif ( strpos ( $clean , ' into outfile ' ) !== false && preg_match ( ' ~(^|[^a-z])into/s+outfile($|[^[a-z])~s ' , $clean ) != 0 ) 86 { 87 $fail = true ; 88 $error = " file fun detect " ; 89 } 90 91 // 老版本的MYSQL不支持子查询,我们的程序里可能也用得少,但是黑客可以使用它来查询数据库敏感信息 92 elseif ( preg_match ( ' ~/([^)]*?select~s ' , $clean ) != 0 ) 93 { 94 $fail = true ; 95 $error = " sub select detect " ; 96 } 97 if ( ! empty ( $fail )) 98 { 99 fputs ( fopen ( $log_file , ' a+ ' ) , " $userIP || $getUrl || $db_string || $error /r/n " ); 100 exit ( " <font size='5' color='red'>Safe Alert: Request Error step 2!</font> " ); 101 } 102 else 103 { 104 return $db_string ; 105 } 106 } |