1 | <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); |
---|
2 | /** |
---|
3 | * CodeIgniter |
---|
4 | * |
---|
5 | * An open source application development framework for PHP 5.1.6 or newer |
---|
6 | * |
---|
7 | * @package CodeIgniter |
---|
8 | * @author ExpressionEngine Dev Team |
---|
9 | * @copyright Copyright (c) 2008 - 2011, EllisLab, Inc. |
---|
10 | * @license http://codeigniter.com/user_guide/license.html |
---|
11 | * @link http://codeigniter.com |
---|
12 | * @since Version 1.0 |
---|
13 | * @filesource |
---|
14 | */ |
---|
15 | |
---|
16 | // ------------------------------------------------------------------------ |
---|
17 | |
---|
18 | /** |
---|
19 | * Input Class |
---|
20 | * |
---|
21 | * Pre-processes global input data for security |
---|
22 | * |
---|
23 | * @package CodeIgniter |
---|
24 | * @subpackage Libraries |
---|
25 | * @category Input |
---|
26 | * @author ExpressionEngine Dev Team |
---|
27 | * @link http://codeigniter.com/user_guide/libraries/input.html |
---|
28 | */ |
---|
29 | class CI_Input { |
---|
30 | |
---|
31 | /** |
---|
32 | * IP address of the current user |
---|
33 | * |
---|
34 | * @var string |
---|
35 | */ |
---|
36 | var $ip_address = FALSE; |
---|
37 | /** |
---|
38 | * user agent (web browser) being used by the current user |
---|
39 | * |
---|
40 | * @var string |
---|
41 | */ |
---|
42 | var $user_agent = FALSE; |
---|
43 | /** |
---|
44 | * If FALSE, then $_GET will be set to an empty array |
---|
45 | * |
---|
46 | * @var bool |
---|
47 | */ |
---|
48 | var $_allow_get_array = TRUE; |
---|
49 | /** |
---|
50 | * If TRUE, then newlines are standardized |
---|
51 | * |
---|
52 | * @var bool |
---|
53 | */ |
---|
54 | var $_standardize_newlines = TRUE; |
---|
55 | /** |
---|
56 | * Determines whether the XSS filter is always active when GET, POST or COOKIE data is encountered |
---|
57 | * Set automatically based on config setting |
---|
58 | * |
---|
59 | * @var bool |
---|
60 | */ |
---|
61 | var $_enable_xss = FALSE; |
---|
62 | /** |
---|
63 | * Enables a CSRF cookie token to be set. |
---|
64 | * Set automatically based on config setting |
---|
65 | * |
---|
66 | * @var bool |
---|
67 | */ |
---|
68 | var $_enable_csrf = FALSE; |
---|
69 | /** |
---|
70 | * List of all HTTP request headers |
---|
71 | * |
---|
72 | * @var array |
---|
73 | */ |
---|
74 | protected $headers = array(); |
---|
75 | |
---|
76 | /** |
---|
77 | * Constructor |
---|
78 | * |
---|
79 | * Sets whether to globally enable the XSS processing |
---|
80 | * and whether to allow the $_GET array |
---|
81 | * |
---|
82 | * @return void |
---|
83 | */ |
---|
84 | public function __construct() |
---|
85 | { |
---|
86 | log_message('debug', "Input Class Initialized"); |
---|
87 | |
---|
88 | $this->_allow_get_array = (config_item('allow_get_array') === TRUE); |
---|
89 | $this->_enable_xss = (config_item('global_xss_filtering') === TRUE); |
---|
90 | $this->_enable_csrf = (config_item('csrf_protection') === TRUE); |
---|
91 | |
---|
92 | global $SEC; |
---|
93 | $this->security =& $SEC; |
---|
94 | |
---|
95 | // Do we need the UTF-8 class? |
---|
96 | if (UTF8_ENABLED === TRUE) |
---|
97 | { |
---|
98 | global $UNI; |
---|
99 | $this->uni =& $UNI; |
---|
100 | } |
---|
101 | |
---|
102 | // Sanitize global arrays |
---|
103 | $this->_sanitize_globals(); |
---|
104 | } |
---|
105 | |
---|
106 | // -------------------------------------------------------------------- |
---|
107 | |
---|
108 | /** |
---|
109 | * Fetch from array |
---|
110 | * |
---|
111 | * This is a helper function to retrieve values from global arrays |
---|
112 | * |
---|
113 | * @access private |
---|
114 | * @param array |
---|
115 | * @param string |
---|
116 | * @param bool |
---|
117 | * @return string |
---|
118 | */ |
---|
119 | function _fetch_from_array(&$array, $index = '', $xss_clean = FALSE) |
---|
120 | { |
---|
121 | if ( ! isset($array[$index])) |
---|
122 | { |
---|
123 | return FALSE; |
---|
124 | } |
---|
125 | |
---|
126 | if ($xss_clean === TRUE) |
---|
127 | { |
---|
128 | return $this->security->xss_clean($array[$index]); |
---|
129 | } |
---|
130 | |
---|
131 | return $array[$index]; |
---|
132 | } |
---|
133 | |
---|
134 | // -------------------------------------------------------------------- |
---|
135 | |
---|
136 | /** |
---|
137 | * Fetch an item from the GET array |
---|
138 | * |
---|
139 | * @access public |
---|
140 | * @param string |
---|
141 | * @param bool |
---|
142 | * @return string |
---|
143 | */ |
---|
144 | function get($index = NULL, $xss_clean = FALSE) |
---|
145 | { |
---|
146 | // Check if a field has been provided |
---|
147 | if ($index === NULL AND ! empty($_GET)) |
---|
148 | { |
---|
149 | $get = array(); |
---|
150 | |
---|
151 | // loop through the full _GET array |
---|
152 | foreach (array_keys($_GET) as $key) |
---|
153 | { |
---|
154 | $get[$key] = $this->_fetch_from_array($_GET, $key, $xss_clean); |
---|
155 | } |
---|
156 | return $get; |
---|
157 | } |
---|
158 | |
---|
159 | return $this->_fetch_from_array($_GET, $index, $xss_clean); |
---|
160 | } |
---|
161 | |
---|
162 | // -------------------------------------------------------------------- |
---|
163 | |
---|
164 | /** |
---|
165 | * Fetch an item from the POST array |
---|
166 | * |
---|
167 | * @access public |
---|
168 | * @param string |
---|
169 | * @param bool |
---|
170 | * @return string |
---|
171 | */ |
---|
172 | function post($index = NULL, $xss_clean = FALSE) |
---|
173 | { |
---|
174 | // Check if a field has been provided |
---|
175 | if ($index === NULL AND ! empty($_POST)) |
---|
176 | { |
---|
177 | $post = array(); |
---|
178 | |
---|
179 | // Loop through the full _POST array and return it |
---|
180 | foreach (array_keys($_POST) as $key) |
---|
181 | { |
---|
182 | $post[$key] = $this->_fetch_from_array($_POST, $key, $xss_clean); |
---|
183 | } |
---|
184 | return $post; |
---|
185 | } |
---|
186 | |
---|
187 | return $this->_fetch_from_array($_POST, $index, $xss_clean); |
---|
188 | } |
---|
189 | |
---|
190 | |
---|
191 | // -------------------------------------------------------------------- |
---|
192 | |
---|
193 | /** |
---|
194 | * Fetch an item from either the GET array or the POST |
---|
195 | * |
---|
196 | * @access public |
---|
197 | * @param string The index key |
---|
198 | * @param bool XSS cleaning |
---|
199 | * @return string |
---|
200 | */ |
---|
201 | function get_post($index = '', $xss_clean = FALSE) |
---|
202 | { |
---|
203 | if ( ! isset($_POST[$index]) ) |
---|
204 | { |
---|
205 | return $this->get($index, $xss_clean); |
---|
206 | } |
---|
207 | else |
---|
208 | { |
---|
209 | return $this->post($index, $xss_clean); |
---|
210 | } |
---|
211 | } |
---|
212 | |
---|
213 | // -------------------------------------------------------------------- |
---|
214 | |
---|
215 | /** |
---|
216 | * Fetch an item from the COOKIE array |
---|
217 | * |
---|
218 | * @access public |
---|
219 | * @param string |
---|
220 | * @param bool |
---|
221 | * @return string |
---|
222 | */ |
---|
223 | function cookie($index = '', $xss_clean = FALSE) |
---|
224 | { |
---|
225 | return $this->_fetch_from_array($_COOKIE, $index, $xss_clean); |
---|
226 | } |
---|
227 | |
---|
228 | // ------------------------------------------------------------------------ |
---|
229 | |
---|
230 | /** |
---|
231 | * Set cookie |
---|
232 | * |
---|
233 | * Accepts six parameter, or you can submit an associative |
---|
234 | * array in the first parameter containing all the values. |
---|
235 | * |
---|
236 | * @access public |
---|
237 | * @param mixed |
---|
238 | * @param string the value of the cookie |
---|
239 | * @param string the number of seconds until expiration |
---|
240 | * @param string the cookie domain. Usually: .yourdomain.com |
---|
241 | * @param string the cookie path |
---|
242 | * @param string the cookie prefix |
---|
243 | * @param bool true makes the cookie secure |
---|
244 | * @return void |
---|
245 | */ |
---|
246 | function set_cookie($name = '', $value = '', $expire = '', $domain = '', $path = '/', $prefix = '', $secure = FALSE) |
---|
247 | { |
---|
248 | if (is_array($name)) |
---|
249 | { |
---|
250 | // always leave 'name' in last place, as the loop will break otherwise, due to $$item |
---|
251 | foreach (array('value', 'expire', 'domain', 'path', 'prefix', 'secure', 'name') as $item) |
---|
252 | { |
---|
253 | if (isset($name[$item])) |
---|
254 | { |
---|
255 | $$item = $name[$item]; |
---|
256 | } |
---|
257 | } |
---|
258 | } |
---|
259 | |
---|
260 | if ($prefix == '' AND config_item('cookie_prefix') != '') |
---|
261 | { |
---|
262 | $prefix = config_item('cookie_prefix'); |
---|
263 | } |
---|
264 | if ($domain == '' AND config_item('cookie_domain') != '') |
---|
265 | { |
---|
266 | $domain = config_item('cookie_domain'); |
---|
267 | } |
---|
268 | if ($path == '/' AND config_item('cookie_path') != '/') |
---|
269 | { |
---|
270 | $path = config_item('cookie_path'); |
---|
271 | } |
---|
272 | if ($secure == FALSE AND config_item('cookie_secure') != FALSE) |
---|
273 | { |
---|
274 | $secure = config_item('cookie_secure'); |
---|
275 | } |
---|
276 | |
---|
277 | if ( ! is_numeric($expire)) |
---|
278 | { |
---|
279 | $expire = time() - 86500; |
---|
280 | } |
---|
281 | else |
---|
282 | { |
---|
283 | $expire = ($expire > 0) ? time() + $expire : 0; |
---|
284 | } |
---|
285 | |
---|
286 | setcookie($prefix.$name, $value, $expire, $path, $domain, $secure); |
---|
287 | } |
---|
288 | |
---|
289 | // -------------------------------------------------------------------- |
---|
290 | |
---|
291 | /** |
---|
292 | * Fetch an item from the SERVER array |
---|
293 | * |
---|
294 | * @access public |
---|
295 | * @param string |
---|
296 | * @param bool |
---|
297 | * @return string |
---|
298 | */ |
---|
299 | function server($index = '', $xss_clean = FALSE) |
---|
300 | { |
---|
301 | return $this->_fetch_from_array($_SERVER, $index, $xss_clean); |
---|
302 | } |
---|
303 | |
---|
304 | // -------------------------------------------------------------------- |
---|
305 | |
---|
306 | /** |
---|
307 | * Fetch the IP Address |
---|
308 | * |
---|
309 | * @return string |
---|
310 | */ |
---|
311 | public function ip_address() |
---|
312 | { |
---|
313 | if ($this->ip_address !== FALSE) |
---|
314 | { |
---|
315 | return $this->ip_address; |
---|
316 | } |
---|
317 | |
---|
318 | $proxy_ips = config_item('proxy_ips'); |
---|
319 | if ( ! empty($proxy_ips)) |
---|
320 | { |
---|
321 | $proxy_ips = explode(',', str_replace(' ', '', $proxy_ips)); |
---|
322 | foreach (array('HTTP_X_FORWARDED_FOR', 'HTTP_CLIENT_IP', 'HTTP_X_CLIENT_IP', 'HTTP_X_CLUSTER_CLIENT_IP') as $header) |
---|
323 | { |
---|
324 | if (($spoof = $this->server($header)) !== FALSE) |
---|
325 | { |
---|
326 | // Some proxies typically list the whole chain of IP |
---|
327 | // addresses through which the client has reached us. |
---|
328 | // e.g. client_ip, proxy_ip1, proxy_ip2, etc. |
---|
329 | if (strpos($spoof, ',') !== FALSE) |
---|
330 | { |
---|
331 | $spoof = explode(',', $spoof, 2); |
---|
332 | $spoof = $spoof[0]; |
---|
333 | } |
---|
334 | |
---|
335 | if ( ! $this->valid_ip($spoof)) |
---|
336 | { |
---|
337 | $spoof = FALSE; |
---|
338 | } |
---|
339 | else |
---|
340 | { |
---|
341 | break; |
---|
342 | } |
---|
343 | } |
---|
344 | } |
---|
345 | |
---|
346 | $this->ip_address = ($spoof !== FALSE && in_array($_SERVER['REMOTE_ADDR'], $proxy_ips, TRUE)) |
---|
347 | ? $spoof : $_SERVER['REMOTE_ADDR']; |
---|
348 | } |
---|
349 | else |
---|
350 | { |
---|
351 | $this->ip_address = $_SERVER['REMOTE_ADDR']; |
---|
352 | } |
---|
353 | |
---|
354 | if ( ! $this->valid_ip($this->ip_address)) |
---|
355 | { |
---|
356 | $this->ip_address = '0.0.0.0'; |
---|
357 | } |
---|
358 | |
---|
359 | return $this->ip_address; |
---|
360 | } |
---|
361 | |
---|
362 | // -------------------------------------------------------------------- |
---|
363 | |
---|
364 | /** |
---|
365 | * Validate IP Address |
---|
366 | * |
---|
367 | * @access public |
---|
368 | * @param string |
---|
369 | * @param string ipv4 or ipv6 |
---|
370 | * @return bool |
---|
371 | */ |
---|
372 | public function valid_ip($ip, $which = '') |
---|
373 | { |
---|
374 | $which = strtolower($which); |
---|
375 | |
---|
376 | // First check if filter_var is available |
---|
377 | if (is_callable('filter_var')) |
---|
378 | { |
---|
379 | switch ($which) { |
---|
380 | case 'ipv4': |
---|
381 | $flag = FILTER_FLAG_IPV4; |
---|
382 | break; |
---|
383 | case 'ipv6': |
---|
384 | $flag = FILTER_FLAG_IPV6; |
---|
385 | break; |
---|
386 | default: |
---|
387 | $flag = ''; |
---|
388 | break; |
---|
389 | } |
---|
390 | |
---|
391 | return (bool) filter_var($ip, FILTER_VALIDATE_IP, $flag); |
---|
392 | } |
---|
393 | |
---|
394 | if ($which !== 'ipv6' && $which !== 'ipv4') |
---|
395 | { |
---|
396 | if (strpos($ip, ':') !== FALSE) |
---|
397 | { |
---|
398 | $which = 'ipv6'; |
---|
399 | } |
---|
400 | elseif (strpos($ip, '.') !== FALSE) |
---|
401 | { |
---|
402 | $which = 'ipv4'; |
---|
403 | } |
---|
404 | else |
---|
405 | { |
---|
406 | return FALSE; |
---|
407 | } |
---|
408 | } |
---|
409 | |
---|
410 | $func = '_valid_'.$which; |
---|
411 | return $this->$func($ip); |
---|
412 | } |
---|
413 | |
---|
414 | // -------------------------------------------------------------------- |
---|
415 | |
---|
416 | /** |
---|
417 | * Validate IPv4 Address |
---|
418 | * |
---|
419 | * Updated version suggested by Geert De Deckere |
---|
420 | * |
---|
421 | * @access protected |
---|
422 | * @param string |
---|
423 | * @return bool |
---|
424 | */ |
---|
425 | protected function _valid_ipv4($ip) |
---|
426 | { |
---|
427 | $ip_segments = explode('.', $ip); |
---|
428 | |
---|
429 | // Always 4 segments needed |
---|
430 | if (count($ip_segments) !== 4) |
---|
431 | { |
---|
432 | return FALSE; |
---|
433 | } |
---|
434 | // IP can not start with 0 |
---|
435 | if ($ip_segments[0][0] == '0') |
---|
436 | { |
---|
437 | return FALSE; |
---|
438 | } |
---|
439 | |
---|
440 | // Check each segment |
---|
441 | foreach ($ip_segments as $segment) |
---|
442 | { |
---|
443 | // IP segments must be digits and can not be |
---|
444 | // longer than 3 digits or greater then 255 |
---|
445 | if ($segment == '' OR preg_match("/[^0-9]/", $segment) OR $segment > 255 OR strlen($segment) > 3) |
---|
446 | { |
---|
447 | return FALSE; |
---|
448 | } |
---|
449 | } |
---|
450 | |
---|
451 | return TRUE; |
---|
452 | } |
---|
453 | |
---|
454 | // -------------------------------------------------------------------- |
---|
455 | |
---|
456 | /** |
---|
457 | * Validate IPv6 Address |
---|
458 | * |
---|
459 | * @access protected |
---|
460 | * @param string |
---|
461 | * @return bool |
---|
462 | */ |
---|
463 | protected function _valid_ipv6($str) |
---|
464 | { |
---|
465 | // 8 groups, separated by : |
---|
466 | // 0-ffff per group |
---|
467 | // one set of consecutive 0 groups can be collapsed to :: |
---|
468 | |
---|
469 | $groups = 8; |
---|
470 | $collapsed = FALSE; |
---|
471 | |
---|
472 | $chunks = array_filter( |
---|
473 | preg_split('/(:{1,2})/', $str, NULL, PREG_SPLIT_DELIM_CAPTURE) |
---|
474 | ); |
---|
475 | |
---|
476 | // Rule out easy nonsense |
---|
477 | if (current($chunks) == ':' OR end($chunks) == ':') |
---|
478 | { |
---|
479 | return FALSE; |
---|
480 | } |
---|
481 | |
---|
482 | // PHP supports IPv4-mapped IPv6 addresses, so we'll expect those as well |
---|
483 | if (strpos(end($chunks), '.') !== FALSE) |
---|
484 | { |
---|
485 | $ipv4 = array_pop($chunks); |
---|
486 | |
---|
487 | if ( ! $this->_valid_ipv4($ipv4)) |
---|
488 | { |
---|
489 | return FALSE; |
---|
490 | } |
---|
491 | |
---|
492 | $groups--; |
---|
493 | } |
---|
494 | |
---|
495 | while ($seg = array_pop($chunks)) |
---|
496 | { |
---|
497 | if ($seg[0] == ':') |
---|
498 | { |
---|
499 | if (--$groups == 0) |
---|
500 | { |
---|
501 | return FALSE; // too many groups |
---|
502 | } |
---|
503 | |
---|
504 | if (strlen($seg) > 2) |
---|
505 | { |
---|
506 | return FALSE; // long separator |
---|
507 | } |
---|
508 | |
---|
509 | if ($seg == '::') |
---|
510 | { |
---|
511 | if ($collapsed) |
---|
512 | { |
---|
513 | return FALSE; // multiple collapsed |
---|
514 | } |
---|
515 | |
---|
516 | $collapsed = TRUE; |
---|
517 | } |
---|
518 | } |
---|
519 | elseif (preg_match("/[^0-9a-f]/i", $seg) OR strlen($seg) > 4) |
---|
520 | { |
---|
521 | return FALSE; // invalid segment |
---|
522 | } |
---|
523 | } |
---|
524 | |
---|
525 | return $collapsed OR $groups == 1; |
---|
526 | } |
---|
527 | |
---|
528 | // -------------------------------------------------------------------- |
---|
529 | |
---|
530 | /** |
---|
531 | * User Agent |
---|
532 | * |
---|
533 | * @access public |
---|
534 | * @return string |
---|
535 | */ |
---|
536 | function user_agent() |
---|
537 | { |
---|
538 | if ($this->user_agent !== FALSE) |
---|
539 | { |
---|
540 | return $this->user_agent; |
---|
541 | } |
---|
542 | |
---|
543 | $this->user_agent = ( ! isset($_SERVER['HTTP_USER_AGENT'])) ? FALSE : $_SERVER['HTTP_USER_AGENT']; |
---|
544 | |
---|
545 | return $this->user_agent; |
---|
546 | } |
---|
547 | |
---|
548 | // -------------------------------------------------------------------- |
---|
549 | |
---|
550 | /** |
---|
551 | * Sanitize Globals |
---|
552 | * |
---|
553 | * This function does the following: |
---|
554 | * |
---|
555 | * Unsets $_GET data (if query strings are not enabled) |
---|
556 | * |
---|
557 | * Unsets all globals if register_globals is enabled |
---|
558 | * |
---|
559 | * Standardizes newline characters to \n |
---|
560 | * |
---|
561 | * @access private |
---|
562 | * @return void |
---|
563 | */ |
---|
564 | function _sanitize_globals() |
---|
565 | { |
---|
566 | // It would be "wrong" to unset any of these GLOBALS. |
---|
567 | $protected = array('_SERVER', '_GET', '_POST', '_FILES', '_REQUEST', |
---|
568 | '_SESSION', '_ENV', 'GLOBALS', 'HTTP_RAW_POST_DATA', |
---|
569 | 'system_folder', 'application_folder', 'BM', 'EXT', |
---|
570 | 'CFG', 'URI', 'RTR', 'OUT', 'IN'); |
---|
571 | |
---|
572 | // Unset globals for securiy. |
---|
573 | // This is effectively the same as register_globals = off |
---|
574 | foreach (array($_GET, $_POST, $_COOKIE) as $global) |
---|
575 | { |
---|
576 | if ( ! is_array($global)) |
---|
577 | { |
---|
578 | if ( ! in_array($global, $protected)) |
---|
579 | { |
---|
580 | global $$global; |
---|
581 | $$global = NULL; |
---|
582 | } |
---|
583 | } |
---|
584 | else |
---|
585 | { |
---|
586 | foreach ($global as $key => $val) |
---|
587 | { |
---|
588 | if ( ! in_array($key, $protected)) |
---|
589 | { |
---|
590 | global $$key; |
---|
591 | $$key = NULL; |
---|
592 | } |
---|
593 | } |
---|
594 | } |
---|
595 | } |
---|
596 | |
---|
597 | // Is $_GET data allowed? If not we'll set the $_GET to an empty array |
---|
598 | if ($this->_allow_get_array == FALSE) |
---|
599 | { |
---|
600 | $_GET = array(); |
---|
601 | } |
---|
602 | else |
---|
603 | { |
---|
604 | if (is_array($_GET) AND count($_GET) > 0) |
---|
605 | { |
---|
606 | foreach ($_GET as $key => $val) |
---|
607 | { |
---|
608 | $_GET[$this->_clean_input_keys($key)] = $this->_clean_input_data($val); |
---|
609 | } |
---|
610 | } |
---|
611 | } |
---|
612 | |
---|
613 | // Clean $_POST Data |
---|
614 | if (is_array($_POST) AND count($_POST) > 0) |
---|
615 | { |
---|
616 | foreach ($_POST as $key => $val) |
---|
617 | { |
---|
618 | $_POST[$this->_clean_input_keys($key)] = $this->_clean_input_data($val); |
---|
619 | } |
---|
620 | } |
---|
621 | |
---|
622 | // Clean $_COOKIE Data |
---|
623 | if (is_array($_COOKIE) AND count($_COOKIE) > 0) |
---|
624 | { |
---|
625 | // Also get rid of specially treated cookies that might be set by a server |
---|
626 | // or silly application, that are of no use to a CI application anyway |
---|
627 | // but that when present will trip our 'Disallowed Key Characters' alarm |
---|
628 | // http://www.ietf.org/rfc/rfc2109.txt |
---|
629 | // note that the key names below are single quoted strings, and are not PHP variables |
---|
630 | unset($_COOKIE['$Version']); |
---|
631 | unset($_COOKIE['$Path']); |
---|
632 | unset($_COOKIE['$Domain']); |
---|
633 | |
---|
634 | foreach ($_COOKIE as $key => $val) |
---|
635 | { |
---|
636 | $_COOKIE[$this->_clean_input_keys($key)] = $this->_clean_input_data($val); |
---|
637 | } |
---|
638 | } |
---|
639 | |
---|
640 | // Sanitize PHP_SELF |
---|
641 | $_SERVER['PHP_SELF'] = strip_tags($_SERVER['PHP_SELF']); |
---|
642 | |
---|
643 | |
---|
644 | // CSRF Protection check on HTTP requests |
---|
645 | if ($this->_enable_csrf == TRUE && ! $this->is_cli_request()) |
---|
646 | { |
---|
647 | $this->security->csrf_verify(); |
---|
648 | } |
---|
649 | |
---|
650 | log_message('debug', "Global POST and COOKIE data sanitized"); |
---|
651 | } |
---|
652 | |
---|
653 | // -------------------------------------------------------------------- |
---|
654 | |
---|
655 | /** |
---|
656 | * Clean Input Data |
---|
657 | * |
---|
658 | * This is a helper function. It escapes data and |
---|
659 | * standardizes newline characters to \n |
---|
660 | * |
---|
661 | * @access private |
---|
662 | * @param string |
---|
663 | * @return string |
---|
664 | */ |
---|
665 | function _clean_input_data($str) |
---|
666 | { |
---|
667 | if (is_array($str)) |
---|
668 | { |
---|
669 | $new_array = array(); |
---|
670 | foreach ($str as $key => $val) |
---|
671 | { |
---|
672 | $new_array[$this->_clean_input_keys($key)] = $this->_clean_input_data($val); |
---|
673 | } |
---|
674 | return $new_array; |
---|
675 | } |
---|
676 | |
---|
677 | /* We strip slashes if magic quotes is on to keep things consistent |
---|
678 | |
---|
679 | NOTE: In PHP 5.4 get_magic_quotes_gpc() will always return 0 and |
---|
680 | it will probably not exist in future versions at all. |
---|
681 | */ |
---|
682 | if ( ! is_php('5.4') && get_magic_quotes_gpc()) |
---|
683 | { |
---|
684 | $str = stripslashes($str); |
---|
685 | } |
---|
686 | |
---|
687 | // Clean UTF-8 if supported |
---|
688 | if (UTF8_ENABLED === TRUE) |
---|
689 | { |
---|
690 | $str = $this->uni->clean_string($str); |
---|
691 | } |
---|
692 | |
---|
693 | // Remove control characters |
---|
694 | $str = remove_invisible_characters($str); |
---|
695 | |
---|
696 | // Should we filter the input data? |
---|
697 | if ($this->_enable_xss === TRUE) |
---|
698 | { |
---|
699 | $str = $this->security->xss_clean($str); |
---|
700 | } |
---|
701 | |
---|
702 | // Standardize newlines if needed |
---|
703 | if ($this->_standardize_newlines == TRUE) |
---|
704 | { |
---|
705 | if (strpos($str, "\r") !== FALSE) |
---|
706 | { |
---|
707 | $str = str_replace(array("\r\n", "\r", "\r\n\n"), PHP_EOL, $str); |
---|
708 | } |
---|
709 | } |
---|
710 | |
---|
711 | return $str; |
---|
712 | } |
---|
713 | |
---|
714 | // -------------------------------------------------------------------- |
---|
715 | |
---|
716 | /** |
---|
717 | * Clean Keys |
---|
718 | * |
---|
719 | * This is a helper function. To prevent malicious users |
---|
720 | * from trying to exploit keys we make sure that keys are |
---|
721 | * only named with alpha-numeric text and a few other items. |
---|
722 | * |
---|
723 | * @access private |
---|
724 | * @param string |
---|
725 | * @return string |
---|
726 | */ |
---|
727 | function _clean_input_keys($str) |
---|
728 | { |
---|
729 | if ( ! preg_match("/^[a-z0-9:_\/-]+$/i", $str)) |
---|
730 | { |
---|
731 | exit('Disallowed Key Characters.'); |
---|
732 | } |
---|
733 | |
---|
734 | // Clean UTF-8 if supported |
---|
735 | if (UTF8_ENABLED === TRUE) |
---|
736 | { |
---|
737 | $str = $this->uni->clean_string($str); |
---|
738 | } |
---|
739 | |
---|
740 | return $str; |
---|
741 | } |
---|
742 | |
---|
743 | // -------------------------------------------------------------------- |
---|
744 | |
---|
745 | /** |
---|
746 | * Request Headers |
---|
747 | * |
---|
748 | * In Apache, you can simply call apache_request_headers(), however for |
---|
749 | * people running other webservers the function is undefined. |
---|
750 | * |
---|
751 | * @param bool XSS cleaning |
---|
752 | * |
---|
753 | * @return array |
---|
754 | */ |
---|
755 | public function request_headers($xss_clean = FALSE) |
---|
756 | { |
---|
757 | // Look at Apache go! |
---|
758 | if (function_exists('apache_request_headers')) |
---|
759 | { |
---|
760 | $headers = apache_request_headers(); |
---|
761 | } |
---|
762 | else |
---|
763 | { |
---|
764 | $headers['Content-Type'] = (isset($_SERVER['CONTENT_TYPE'])) ? $_SERVER['CONTENT_TYPE'] : @getenv('CONTENT_TYPE'); |
---|
765 | |
---|
766 | foreach ($_SERVER as $key => $val) |
---|
767 | { |
---|
768 | if (strncmp($key, 'HTTP_', 5) === 0) |
---|
769 | { |
---|
770 | $headers[substr($key, 5)] = $this->_fetch_from_array($_SERVER, $key, $xss_clean); |
---|
771 | } |
---|
772 | } |
---|
773 | } |
---|
774 | |
---|
775 | // take SOME_HEADER and turn it into Some-Header |
---|
776 | foreach ($headers as $key => $val) |
---|
777 | { |
---|
778 | $key = str_replace('_', ' ', strtolower($key)); |
---|
779 | $key = str_replace(' ', '-', ucwords($key)); |
---|
780 | |
---|
781 | $this->headers[$key] = $val; |
---|
782 | } |
---|
783 | |
---|
784 | return $this->headers; |
---|
785 | } |
---|
786 | |
---|
787 | // -------------------------------------------------------------------- |
---|
788 | |
---|
789 | /** |
---|
790 | * Get Request Header |
---|
791 | * |
---|
792 | * Returns the value of a single member of the headers class member |
---|
793 | * |
---|
794 | * @param string array key for $this->headers |
---|
795 | * @param boolean XSS Clean or not |
---|
796 | * @return mixed FALSE on failure, string on success |
---|
797 | */ |
---|
798 | public function get_request_header($index, $xss_clean = FALSE) |
---|
799 | { |
---|
800 | if (empty($this->headers)) |
---|
801 | { |
---|
802 | $this->request_headers(); |
---|
803 | } |
---|
804 | |
---|
805 | if ( ! isset($this->headers[$index])) |
---|
806 | { |
---|
807 | return FALSE; |
---|
808 | } |
---|
809 | |
---|
810 | if ($xss_clean === TRUE) |
---|
811 | { |
---|
812 | return $this->security->xss_clean($this->headers[$index]); |
---|
813 | } |
---|
814 | |
---|
815 | return $this->headers[$index]; |
---|
816 | } |
---|
817 | |
---|
818 | // -------------------------------------------------------------------- |
---|
819 | |
---|
820 | /** |
---|
821 | * Is ajax Request? |
---|
822 | * |
---|
823 | * Test to see if a request contains the HTTP_X_REQUESTED_WITH header |
---|
824 | * |
---|
825 | * @return boolean |
---|
826 | */ |
---|
827 | public function is_ajax_request() |
---|
828 | { |
---|
829 | return ($this->server('HTTP_X_REQUESTED_WITH') === 'XMLHttpRequest'); |
---|
830 | } |
---|
831 | |
---|
832 | // -------------------------------------------------------------------- |
---|
833 | |
---|
834 | /** |
---|
835 | * Is cli Request? |
---|
836 | * |
---|
837 | * Test to see if a request was made from the command line |
---|
838 | * |
---|
839 | * @return bool |
---|
840 | */ |
---|
841 | public function is_cli_request() |
---|
842 | { |
---|
843 | return (php_sapi_name() === 'cli' OR defined('STDIN')); |
---|
844 | } |
---|
845 | |
---|
846 | } |
---|
847 | |
---|
848 | /* End of file Input.php */ |
---|
849 | /* Location: ./system/core/Input.php */ |
---|