1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10:
11:
12: 13: 14: 15: 16: 17: 18: 19: 20:
21:
22: $root_path = \XoopsBaseConfig::get('root-path');
23: $db_type = \XoopsBaseConfig::get('db-type');
24:
25: if( XoopsLoad::fileExists( $root_path.'/class/database/drivers/'.$db_type.'/database.php' ) ) {
26: require_once $root_path.'/class/database/drivers/'.$db_type.'/database.php';
27: } else {
28: require_once $root_path.'/class/database/'.$db_type.'database.php';
29: }
30:
31: require_once $root_path.'/class/database/database.php' ;
32:
33: class ProtectorMySQLDatabase extends XoopsMySQLDatabaseProxy
34: {
35:
36: var $doubtful_requests = array() ;
37: var $doubtful_needles = array(
38:
39: 'concat' ,
40: 'information_schema' ,
41: 'select' ,
42: 'union' ,
43: '/*' ,
44: '--' ,
45: '#' ,
46: ) ;
47:
48:
49: function ProtectorMySQLDatabase()
50: {
51: $protector = Protector::getInstance() ;
52: $this->doubtful_requests = $protector->getDblayertrapDoubtfuls() ;
53: $this->doubtful_needles = array_merge( $this->doubtful_needles , $this->doubtful_requests ) ;
54: }
55:
56:
57: function injectionFound( $sql )
58: {
59: $protector = Protector::getInstance() ;
60:
61: $protector->last_error_type = 'SQL Injection' ;
62: $protector->message .= $sql ;
63: $protector->output_log( $protector->last_error_type ) ;
64: die( 'SQL Injection found' ) ;
65: }
66:
67:
68: function separateStringsInSQL( $sql )
69: {
70: $sql = trim( $sql ) ;
71: $sql_len = strlen( $sql ) ;
72: $char = '' ;
73: $string_start = '' ;
74: $in_string = false;
75: $sql_wo_string = '' ;
76: $strings = array() ;
77: $current_string = '' ;
78:
79: for( $i = 0 ; $i < $sql_len ; ++$i ) {
80: $char = $sql[$i] ;
81: if( $in_string ) {
82: while( 1 ) {
83: $new_i = strpos( $sql , $string_start , $i ) ;
84: $current_string .= substr( $sql , $i , $new_i - $i + 1 ) ;
85: $i = $new_i ;
86: if( $i === false ) {
87: break 2 ;
88: } else if( $sql[$i-1] !== '\\' ) {
89: $string_start = '' ;
90: $in_string = false ;
91: $strings[] = $current_string ;
92: break ;
93: } else {
94: $j = 2 ;
95: $escaped_backslash = false ;
96: while( $i - $j > 0 && $sql[$i-$j] === '\\' ) {
97: $escaped_backslash = ! $escaped_backslash ;
98: ++$j;
99: }
100: if ($escaped_backslash) {
101: $string_start = '' ;
102: $in_string = false ;
103: $strings[] = $current_string ;
104: break ;
105: } else {
106: ++$i;
107: }
108: }
109: }
110: } else if( $char === '"' || $char === "'" ) {
111: $in_string = true ;
112: $string_start = $char ;
113: $current_string = $char ;
114: } else {
115: $sql_wo_string .= $char ;
116: }
117:
118:
119: }
120:
121: return array( $sql_wo_string , $strings ) ;
122: }
123:
124:
125:
126: 127: 128:
129: function checkSql( $sql )
130: {
131: list( $sql_wo_strings , $strings ) = $this->separateStringsInSQL( $sql ) ;
132:
133:
134: foreach( $this->doubtful_requests as $request ) {
135: if( addslashes( $request ) != $request ) {
136: if( stristr( $sql , trim( $request ) ) ) {
137:
138: $ok_flag = false ;
139: foreach( $strings as $string ) {
140: if( strstr( $string , $request ) ) {
141: $ok_flag = true ;
142: break ;
143: }
144: }
145: if( ! $ok_flag ) {
146: $this->injectionFound( $sql ) ;
147: }
148: }
149: }
150: }
151:
152:
153:
154:
155:
156:
157:
158: foreach( $this->doubtful_requests as $request ) {
159: if( strstr( $sql_wo_strings , trim( $request ) ) ) {
160: $this->injectionFound( $sql ) ;
161: }
162: }
163:
164:
165: if( preg_match( '/(\/\*|\-\-|\#)/' , $sql_wo_strings , $regs ) ) {
166: foreach( $this->doubtful_requests as $request ) {
167: if( strstr( $request , $regs[1] ) ) {
168: $this->injectionFound( $sql ) ;
169: }
170: }
171: }
172: }
173:
174:
175: function query( $sql , $limit = 0 , $start = 0 )
176: {
177: $sql4check = substr( $sql , 7 ) ;
178: foreach( $this->doubtful_needles as $needle ) {
179: if( stristr( $sql4check , $needle ) ) {
180: $this->checkSql( $sql ) ;
181: break ;
182: }
183: }
184:
185: if( ! defined( 'XOOPS_DB_PROXY' ) ) {
186: $ret = parent::queryF( $sql , $limit , $start ) ;
187: } else {
188: $ret = parent::query( $sql , $limit , $start ) ;
189: }
190: return $ret ;
191: }
192:
193: }
194: