1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
15:
16: defined('CON_FRAMEWORK') || die('Illegal call: Missing framework initialization - request aborted.');
17:
18: 19: 20: 21: 22: 23:
24: class cRequestValidator {
25:
26: 27: 28: 29: 30:
31: private static $_instance = NULL;
32:
33: 34: 35: 36: 37:
38: protected $_logPath;
39:
40: 41: 42: 43: 44:
45: protected $_log = true;
46:
47: 48: 49: 50: 51:
52: protected $_configPath;
53:
54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66:
67: protected $_check = array();
68:
69: 70: 71: 72: 73: 74:
75: protected $_blacklist = array();
76:
77: 78: 79: 80: 81:
82: protected $_failure = '';
83:
84: 85: 86: 87: 88:
89: protected $_mode = '';
90:
91: 92: 93: 94: 95:
96: const CHECK_INTEGER = '/^[0-9]*$/';
97:
98: 99: 100: 101: 102:
103: const CHECK_PRIMITIVESTRING = '/^[a-zA-Z0-9 -_]*$/';
104:
105: 106: 107: 108: 109:
110: const CHECK_STRING = '/^[\w0-9 -_]*$/';
111:
112: 113: 114: 115: 116:
117: const CHECK_HASH32 = '/^[a-zA-Z0-9]{32}$/';
118:
119: 120: 121: 122: 123:
124: const CHECK_BELANG = '/^[a-z]{2}_[A-Z]{2}$/';
125:
126: 127: 128: 129: 130:
131: const CHECK_AREASTRING = '/^[a-zA-Z_]*$/';
132:
133: 134: 135: 136: 137:
138: const CHECK_PATHSTRING = '!([*]*\/)|(dbfs:\/[*]*)|(dbfs:)|(^)$!';
139:
140: 141: 142: 143: 144: 145: 146: 147:
148: private function __construct() {
149:
150: global $bLog, $sMode, $aCheck, $aBlacklist;
151:
152:
153: $installationPath = str_replace('\\', '/', realpath(dirname(__FILE__) . '/../..'));
154: $configPath = $installationPath . '/data/config/' . CON_ENVIRONMENT;
155:
156: $this->_logPath = $installationPath . '/data/logs/security.txt';
157:
158:
159: if (cFileHandler::exists($configPath . '/config.http_check.php')) {
160: $this->_configPath = $configPath;
161: } else {
162: throw new cFileNotFoundException('Could not load cRequestValidator configuration! (invalid path) ' . $configPath . '/config.http_check.php');
163: }
164:
165:
166: require($this->_configPath . '/config.http_check.php');
167:
168:
169: if (cFileHandler::exists($this->_configPath . '/config.http_check.local.php')) {
170: require($this->_configPath . '/config.http_check.local.php');
171: }
172:
173: $this->_log = $bLog;
174: $this->_mode = $sMode;
175:
176: if ($this->_log === true) {
177: if (empty($this->_logPath) || !is_writeable(dirname($this->_logPath))) {
178: $this->_log = false;
179: }
180: }
181:
182: $this->_check = $aCheck;
183: foreach ($aBlacklist as $elem) {
184: $this->_blacklist[] = strtolower($elem);
185: }
186: }
187:
188: 189: 190: 191: 192:
193: public static function getInstance() {
194: if (self::$_instance === NULL) {
195: self::$_instance = new self();
196: }
197:
198: return self::$_instance;
199: }
200:
201: 202: 203: 204: 205: 206: 207:
208: public function checkParams() {
209: if ((!$this->checkGetParams()) || (!$this->checkPostParams())) {
210: $this->logHackTrial();
211:
212: if ($this->_mode == 'stop') {
213: ob_end_clean();
214: die('Parameter check failed! (' . $this->_failure . '=' . $_GET[$this->_failure] . $_POST[$this->_failure] . ')');
215: }
216: }
217:
218: return true;
219: }
220:
221: 222: 223: 224: 225: 226:
227: public function checkGetParams() {
228: return $this->checkArray($_GET, 'GET');
229: }
230:
231: 232: 233: 234: 235: 236:
237: public function checkPostParams() {
238: return $this->checkArray($_POST, 'POST');
239: }
240:
241: 242: 243: 244: 245: 246: 247: 248: 249: 250:
251: public function checkParameter($type, $key, $value) {
252: $result = false;
253:
254: if (in_array(strtolower($key), $this->_blacklist)) {
255: return false;
256: }
257:
258: if (in_array(strtoupper($type), array(
259: 'GET',
260: 'POST'
261: ))) {
262: if (!isset($this->_check[$type][$key]) && (is_null($value) || empty($value))) {
263:
264: $result = true;
265: } elseif (isset($this->_check[$type][$key])) {
266:
267: $result = preg_match($this->_check[$type][$key], $value);
268: } else {
269:
270: $result = true;
271: }
272: }
273:
274: return $result;
275: }
276:
277: 278: 279: 280: 281:
282: public function getBadParameter() {
283: return $this->_failure;
284: }
285:
286: 287: 288: 289:
290: protected function logHackTrial() {
291: if ($this->_log === true && !empty($this->_logPath)) {
292: $content = date('Y-m-d H:i:s') . ' ';
293: $content .= $_SERVER['REMOTE_ADDR'] . str_repeat(' ', 17 - strlen($_SERVER['REMOTE_ADDR'])) . "\n";
294: $content .= ' Query String: ' . $_SERVER['QUERY_STRING'] . "\n";
295: $content .= ' Bad parameter: ' . $this->getBadParameter() . "\n";
296: $content .= ' POST array: ' . print_r($_POST, true) . "\n";
297: cFileHandler::write($this->_logPath, $content, true);
298: } elseif ($this->_mode == 'continue') {
299: echo "\n<br>VIOLATION: URL contains invalid or undefined paramaters! URL: '" . conHtmlentities($_SERVER['QUERY_STRING']) . "' <br>\n";
300: }
301: }
302:
303: 304: 305: 306: 307: 308: 309: 310:
311: protected function checkArray($arr, $type) {
312: $result = true;
313:
314: foreach ($arr as $key => $value) {
315: if (!$this->checkParameter(strtoupper($type), $key, $value)) {
316: $this->_failure = $key;
317: $result = false;
318: break;
319: }
320: }
321:
322: return $result;
323: }
324:
325: }
326: