PluginProbe
ShiftController Employee Shift Scheduling / 2.2.0
ShiftController Employee Shift Scheduling v2.2.0
4.9.97 4.9.96 4.9.95 4.9.74 4.9.75 4.9.76 4.9.77 4.9.78 4.9.84 4.9.85 4.9.87 4.9.91 4.9.92 trunk 2.1.0 2.1.1 2.1.2 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 3.2.4 All 38 releases
shiftcontroller / happ / system / core / Input.php

Input.php in ShiftController Employee Shift Scheduling 2.2.0, at happ/system/core/Input.php

853 lines 18.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
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 (
683 ( ! is_php('5.4') && get_magic_quotes_gpc() )
684 OR
685 ( isset($GLOBALS['NTS_IS_PLUGIN']) && ($GLOBALS['NTS_IS_PLUGIN'] == 'wordpress') )
686 )
687 {
688 $str = stripslashes($str);
689 }
690
691 // Clean UTF-8 if supported
692 if (UTF8_ENABLED === TRUE)
693 {
694 $str = $this->uni->clean_string($str);
695 }
696
697 // Remove control characters
698 $str = remove_invisible_characters($str);
699
700 // Should we filter the input data?
701 if ($this->_enable_xss === TRUE)
702 {
703 $str = $this->security->xss_clean($str);
704 }
705
706 // Standardize newlines if needed
707 if ($this->_standardize_newlines == TRUE)
708 {
709 if (strpos($str, "\r") !== FALSE)
710 {
711 $str = str_replace(array("\r\n", "\r", "\r\n\n"), PHP_EOL, $str);
712 }
713 }
714
715 return $str;
716 }
717
718 // --------------------------------------------------------------------
719
720 /**
721 * Clean Keys
722 *
723 * This is a helper function. To prevent malicious users
724 * from trying to exploit keys we make sure that keys are
725 * only named with alpha-numeric text and a few other items.
726 *
727 * @access private
728 * @param string
729 * @return string
730 */
731 function _clean_input_keys($str)
732 {
733 if ( ! preg_match("/^[a-z0-9:_\/-]+$/i", $str))
734 {
735 exit('Disallowed Key Characters.');
736 }
737
738 // Clean UTF-8 if supported
739 if (UTF8_ENABLED === TRUE)
740 {
741 $str = $this->uni->clean_string($str);
742 }
743
744 return $str;
745 }
746
747 // --------------------------------------------------------------------
748
749 /**
750 * Request Headers
751 *
752 * In Apache, you can simply call apache_request_headers(), however for
753 * people running other webservers the function is undefined.
754 *
755 * @param bool XSS cleaning
756 *
757 * @return array
758 */
759 public function request_headers($xss_clean = FALSE)
760 {
761 // Look at Apache go!
762 if (function_exists('apache_request_headers'))
763 {
764 $headers = apache_request_headers();
765 }
766 else
767 {
768 $headers['Content-Type'] = (isset($_SERVER['CONTENT_TYPE'])) ? $_SERVER['CONTENT_TYPE'] : @getenv('CONTENT_TYPE');
769
770 foreach ($_SERVER as $key => $val)
771 {
772 if (strncmp($key, 'HTTP_', 5) === 0)
773 {
774 $headers[substr($key, 5)] = $this->_fetch_from_array($_SERVER, $key, $xss_clean);
775 }
776 }
777 }
778
779 // take SOME_HEADER and turn it into Some-Header
780 foreach ($headers as $key => $val)
781 {
782 $key = str_replace('_', ' ', strtolower($key));
783 $key = str_replace(' ', '-', ucwords($key));
784
785 $this->headers[$key] = $val;
786 }
787
788 return $this->headers;
789 }
790
791 // --------------------------------------------------------------------
792
793 /**
794 * Get Request Header
795 *
796 * Returns the value of a single member of the headers class member
797 *
798 * @param string array key for $this->headers
799 * @param boolean XSS Clean or not
800 * @return mixed FALSE on failure, string on success
801 */
802 public function get_request_header($index, $xss_clean = FALSE)
803 {
804 if (empty($this->headers))
805 {
806 $this->request_headers();
807 }
808
809 if ( ! isset($this->headers[$index]))
810 {
811 return FALSE;
812 }
813
814 if ($xss_clean === TRUE)
815 {
816 return $this->security->xss_clean($this->headers[$index]);
817 }
818
819 return $this->headers[$index];
820 }
821
822 // --------------------------------------------------------------------
823
824 /**
825 * Is ajax Request?
826 *
827 * Test to see if a request contains the HTTP_X_REQUESTED_WITH header
828 *
829 * @return boolean
830 */
831 public function is_ajax_request()
832 {
833 return ($this->server('HTTP_X_REQUESTED_WITH') === 'XMLHttpRequest');
834 }
835
836 // --------------------------------------------------------------------
837
838 /**
839 * Is cli Request?
840 *
841 * Test to see if a request was made from the command line
842 *
843 * @return bool
844 */
845 public function is_cli_request()
846 {
847 return (php_sapi_name() === 'cli' OR defined('STDIN'));
848 }
849
850 }
851
852 /* End of file Input.php */
853 /* Location: ./system/core/Input.php */