blob: 946d9296f32c39b407fd4d9d01cdfe1d67a867fb [file] [log] [blame]
Derek Jones37f4b9c2011-07-01 17:56:50 -05001<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
Derek Allard2067d1a2008-11-13 22:59:24 +00002/**
3 * CodeIgniter
4 *
Greg Aker741de1c2010-11-10 14:52:57 -06005 * An open source application development framework for PHP 5.1.6 or newer
Derek Allard2067d1a2008-11-13 22:59:24 +00006 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -05007 * NOTICE OF LICENSE
8 *
9 * Licensed under the Open Software License version 3.0
10 *
11 * This source file is subject to the Open Software License (OSL 3.0) that is
12 * bundled with this package in the files license.txt / license.rst. It is
13 * also available through the world wide web at this URL:
14 * http://opensource.org/licenses/OSL-3.0
15 * If you did not receive a copy of the license and are unable to obtain it
16 * through the world wide web, please send an email to
17 * licensing@ellislab.com so we can send you a copy immediately.
18 *
Derek Allard2067d1a2008-11-13 22:59:24 +000019 * @package CodeIgniter
Derek Jonesf4a4bd82011-10-20 12:18:42 -050020 * @author EllisLab Dev Team
21 * @copyright Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
22 * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
Derek Allard2067d1a2008-11-13 22:59:24 +000023 * @link http://codeigniter.com
24 * @since Version 1.0
25 * @filesource
26 */
27
28// ------------------------------------------------------------------------
29
30/**
31 * Input Class
32 *
33 * Pre-processes global input data for security
34 *
35 * @package CodeIgniter
36 * @subpackage Libraries
37 * @category Input
Derek Jonesf4a4bd82011-10-20 12:18:42 -050038 * @author EllisLab Dev Team
Derek Allard2067d1a2008-11-13 22:59:24 +000039 * @link http://codeigniter.com/user_guide/libraries/input.html
40 */
41class CI_Input {
Derek Allard2067d1a2008-11-13 22:59:24 +000042
David Behler9b5df592011-08-14 21:04:17 +020043 /**
44 * IP address of the current user
45 *
46 * @var string
47 */
Derek Jones69fc4fc2010-03-02 13:36:31 -060048 var $ip_address = FALSE;
David Behler9b5df592011-08-14 21:04:17 +020049 /**
50 * user agent (web browser) being used by the current user
51 *
52 * @var string
53 */
Derek Jones69fc4fc2010-03-02 13:36:31 -060054 var $user_agent = FALSE;
David Behler9b5df592011-08-14 21:04:17 +020055 /**
56 * If FALSE, then $_GET will be set to an empty array
57 *
58 * @var bool
59 */
Dan Horrigan65d603e2010-12-15 08:38:30 -050060 var $_allow_get_array = TRUE;
David Behler9b5df592011-08-14 21:04:17 +020061 /**
62 * If TRUE, then newlines are standardized
63 *
64 * @var bool
65 */
Derek Jones69fc4fc2010-03-02 13:36:31 -060066 var $_standardize_newlines = TRUE;
David Behler9b5df592011-08-14 21:04:17 +020067 /**
68 * Determines whether the XSS filter is always active when GET, POST or COOKIE data is encountered
69 * Set automatically based on config setting
70 *
71 * @var bool
72 */
73 var $_enable_xss = FALSE;
74 /**
75 * Enables a CSRF cookie token to be set.
76 * Set automatically based on config setting
77 *
78 * @var bool
79 */
80 var $_enable_csrf = FALSE;
81 /**
82 * List of all HTTP request headers
83 *
84 * @var array
85 */
Greg Akerec2f5712010-11-15 16:22:12 -060086 protected $headers = array();
David Behler9b5df592011-08-14 21:04:17 +020087
Greg Akerec2f5712010-11-15 16:22:12 -060088
Derek Allard2067d1a2008-11-13 22:59:24 +000089 /**
Greg Akera9263282010-11-10 15:26:43 -060090 * Constructor
91 *
92 * Sets whether to globally enable the XSS processing
93 * and whether to allow the $_GET array
94 *
95 */
96 public function __construct()
Derek Allard2067d1a2008-11-13 22:59:24 +000097 {
98 log_message('debug', "Input Class Initialized");
99
Phil Sturgeonc8089152010-12-27 19:06:28 +0000100 $this->_allow_get_array = (config_item('allow_get_array') === TRUE);
101 $this->_enable_xss = (config_item('global_xss_filtering') === TRUE);
102 $this->_enable_csrf = (config_item('csrf_protection') === TRUE);
Derek Jones69fc4fc2010-03-02 13:36:31 -0600103
Pascal Kriete14a0ac62011-04-05 14:55:56 -0400104 global $SEC;
105 $this->security =& $SEC;
Derek Jones69fc4fc2010-03-02 13:36:31 -0600106
Pascal Krieteaaec1e42011-01-20 00:01:21 -0500107 // Do we need the UTF-8 class?
Derek Jones69fc4fc2010-03-02 13:36:31 -0600108 if (UTF8_ENABLED === TRUE)
109 {
110 global $UNI;
111 $this->uni =& $UNI;
112 }
113
114 // Sanitize global arrays
Derek Allard2067d1a2008-11-13 22:59:24 +0000115 $this->_sanitize_globals();
116 }
117
118 // --------------------------------------------------------------------
119
120 /**
Greg Akera9263282010-11-10 15:26:43 -0600121 * Fetch from array
122 *
123 * This is a helper function to retrieve values from global arrays
124 *
Bo-Yi Wu47213792011-09-13 22:44:07 +0800125 * @access protected
Greg Akera9263282010-11-10 15:26:43 -0600126 * @param array
127 * @param string
128 * @param bool
129 * @return string
130 */
Bo-Yi Wu47213792011-09-13 22:44:07 +0800131 protected function _fetch_from_array(&$array, $index = '', $xss_clean = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000132 {
133 if ( ! isset($array[$index]))
134 {
135 return FALSE;
136 }
137
138 if ($xss_clean === TRUE)
139 {
Pascal Kriete14a0ac62011-04-05 14:55:56 -0400140 return $this->security->xss_clean($array[$index]);
Derek Allard2067d1a2008-11-13 22:59:24 +0000141 }
142
143 return $array[$index];
144 }
145
146 // --------------------------------------------------------------------
147
148 /**
149 * Fetch an item from the GET array
150 *
151 * @access public
152 * @param string
153 * @param bool
154 * @return string
155 */
Bo-Yi Wu4db872f2011-09-12 10:52:37 +0800156 public function get($index = NULL, $xss_clean = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000157 {
Phil Sturgeon44f21052011-02-15 21:39:25 +0000158 // Check if a field has been provided
159 if ($index === NULL AND ! empty($_GET))
vascopjff1cfa12011-02-13 21:30:19 +0000160 {
Phil Sturgeon44f21052011-02-15 21:39:25 +0000161 $get = array();
vascopjff1cfa12011-02-13 21:30:19 +0000162
163 // loop through the full _GET array
Phil Sturgeon44f21052011-02-15 21:39:25 +0000164 foreach (array_keys($_GET) as $key)
vascopjff1cfa12011-02-13 21:30:19 +0000165 {
Phil Sturgeon44f21052011-02-15 21:39:25 +0000166 $get[$key] = $this->_fetch_from_array($_GET, $key, $xss_clean);
vascopjff1cfa12011-02-13 21:30:19 +0000167 }
Phil Sturgeon44f21052011-02-15 21:39:25 +0000168 return $get;
vascopjff1cfa12011-02-13 21:30:19 +0000169 }
170
Derek Allard2067d1a2008-11-13 22:59:24 +0000171 return $this->_fetch_from_array($_GET, $index, $xss_clean);
172 }
173
174 // --------------------------------------------------------------------
175
176 /**
177 * Fetch an item from the POST array
178 *
179 * @access public
180 * @param string
181 * @param bool
182 * @return string
183 */
Bo-Yi Wu4db872f2011-09-12 10:52:37 +0800184 public function post($index = NULL, $xss_clean = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000185 {
Phil Sturgeon44f21052011-02-15 21:39:25 +0000186 // Check if a field has been provided
187 if ($index === NULL AND ! empty($_POST))
vascopj0ba58b82011-02-06 14:20:21 +0000188 {
Phil Sturgeon44f21052011-02-15 21:39:25 +0000189 $post = array();
vascopj0ba58b82011-02-06 14:20:21 +0000190
Phil Sturgeon44f21052011-02-15 21:39:25 +0000191 // Loop through the full _POST array and return it
192 foreach (array_keys($_POST) as $key)
vascopj0ba58b82011-02-06 14:20:21 +0000193 {
Phil Sturgeon44f21052011-02-15 21:39:25 +0000194 $post[$key] = $this->_fetch_from_array($_POST, $key, $xss_clean);
vascopj0ba58b82011-02-06 14:20:21 +0000195 }
Phil Sturgeon44f21052011-02-15 21:39:25 +0000196 return $post;
vascopj0ba58b82011-02-06 14:20:21 +0000197 }
David Behler9b5df592011-08-14 21:04:17 +0200198
Derek Allard2067d1a2008-11-13 22:59:24 +0000199 return $this->_fetch_from_array($_POST, $index, $xss_clean);
200 }
201
Derek Jones69fc4fc2010-03-02 13:36:31 -0600202
Derek Allard2067d1a2008-11-13 22:59:24 +0000203 // --------------------------------------------------------------------
204
205 /**
206 * Fetch an item from either the GET array or the POST
207 *
208 * @access public
209 * @param string The index key
210 * @param bool XSS cleaning
211 * @return string
212 */
Bo-Yi Wu4db872f2011-09-12 10:52:37 +0800213 public function get_post($index = '', $xss_clean = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000214 {
215 if ( ! isset($_POST[$index]) )
216 {
217 return $this->get($index, $xss_clean);
218 }
219 else
220 {
221 return $this->post($index, $xss_clean);
222 }
223 }
224
225 // --------------------------------------------------------------------
226
227 /**
228 * Fetch an item from the COOKIE array
229 *
230 * @access public
231 * @param string
232 * @param bool
233 * @return string
234 */
Bo-Yi Wu4db872f2011-09-12 10:52:37 +0800235 public function cookie($index = '', $xss_clean = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000236 {
237 return $this->_fetch_from_array($_COOKIE, $index, $xss_clean);
238 }
239
Derek Jones69fc4fc2010-03-02 13:36:31 -0600240 // ------------------------------------------------------------------------
241
242 /**
243 * Set cookie
244 *
245 * Accepts six parameter, or you can submit an associative
246 * array in the first parameter containing all the values.
247 *
248 * @access public
249 * @param mixed
250 * @param string the value of the cookie
251 * @param string the number of seconds until expiration
Derek Jones37f4b9c2011-07-01 17:56:50 -0500252 * @param string the cookie domain. Usually: .yourdomain.com
Derek Jones69fc4fc2010-03-02 13:36:31 -0600253 * @param string the cookie path
254 * @param string the cookie prefix
Phil Sturgeond8d1e242011-02-16 17:23:16 +0000255 * @param bool true makes the cookie secure
Derek Jones69fc4fc2010-03-02 13:36:31 -0600256 * @return void
257 */
Bo-Yi Wu4db872f2011-09-12 10:52:37 +0800258 public function set_cookie($name = '', $value = '', $expire = '', $domain = '', $path = '/', $prefix = '', $secure = FALSE)
Derek Jones69fc4fc2010-03-02 13:36:31 -0600259 {
260 if (is_array($name))
261 {
tobiasbg9aa7dc92011-02-18 21:57:13 +0100262 // always leave 'name' in last place, as the loop will break otherwise, due to $$item
263 foreach (array('value', 'expire', 'domain', 'path', 'prefix', 'secure', 'name') as $item)
Derek Jones69fc4fc2010-03-02 13:36:31 -0600264 {
265 if (isset($name[$item]))
266 {
267 $$item = $name[$item];
268 }
269 }
270 }
271
272 if ($prefix == '' AND config_item('cookie_prefix') != '')
273 {
274 $prefix = config_item('cookie_prefix');
275 }
276 if ($domain == '' AND config_item('cookie_domain') != '')
277 {
278 $domain = config_item('cookie_domain');
279 }
280 if ($path == '/' AND config_item('cookie_path') != '/')
281 {
282 $path = config_item('cookie_path');
283 }
tobiasbg9aa7dc92011-02-18 21:57:13 +0100284 if ($secure == FALSE AND config_item('cookie_secure') != FALSE)
285 {
286 $secure = config_item('cookie_secure');
287 }
Derek Jones69fc4fc2010-03-02 13:36:31 -0600288
289 if ( ! is_numeric($expire))
290 {
291 $expire = time() - 86500;
292 }
293 else
294 {
Phil Sturgeonc8089152010-12-27 19:06:28 +0000295 $expire = ($expire > 0) ? time() + $expire : 0;
Derek Jones69fc4fc2010-03-02 13:36:31 -0600296 }
297
Phil Sturgeond8d1e242011-02-16 17:23:16 +0000298 setcookie($prefix.$name, $value, $expire, $path, $domain, $secure);
Derek Jones69fc4fc2010-03-02 13:36:31 -0600299 }
300
Derek Allard2067d1a2008-11-13 22:59:24 +0000301 // --------------------------------------------------------------------
302
303 /**
304 * Fetch an item from the SERVER array
305 *
306 * @access public
307 * @param string
308 * @param bool
309 * @return string
310 */
Bo-Yi Wu4db872f2011-09-12 10:52:37 +0800311 public function server($index = '', $xss_clean = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000312 {
313 return $this->_fetch_from_array($_SERVER, $index, $xss_clean);
314 }
315
316 // --------------------------------------------------------------------
317
318 /**
319 * Fetch the IP Address
320 *
321 * @access public
322 * @return string
323 */
Bo-Yi Wu4db872f2011-09-12 10:52:37 +0800324 public function ip_address()
Derek Allard2067d1a2008-11-13 22:59:24 +0000325 {
326 if ($this->ip_address !== FALSE)
327 {
328 return $this->ip_address;
329 }
Barry Mienydd671972010-10-04 16:33:58 +0200330
Derek Jones42b2e172009-02-05 16:59:45 +0000331 if (config_item('proxy_ips') != '' && $this->server('HTTP_X_FORWARDED_FOR') && $this->server('REMOTE_ADDR'))
Derek Jonesc5972282009-02-04 21:40:20 +0000332 {
Derek Jones42b2e172009-02-05 16:59:45 +0000333 $proxies = preg_split('/[\s,]/', config_item('proxy_ips'), -1, PREG_SPLIT_NO_EMPTY);
Derek Jonesc5972282009-02-04 21:40:20 +0000334 $proxies = is_array($proxies) ? $proxies : array($proxies);
Derek Allard2067d1a2008-11-13 22:59:24 +0000335
Derek Jonesc5972282009-02-04 21:40:20 +0000336 $this->ip_address = in_array($_SERVER['REMOTE_ADDR'], $proxies) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR'];
337 }
John Bellone16f27b42011-08-21 11:45:11 -0400338 elseif (! $this->server('HTTP_CLIENT_IP') AND $this->server('REMOTE_ADDR'))
John Bellone52c10b62011-08-21 11:41:32 -0400339 {
340 $this->ip_address = $_SERVER['REMOTE_ADDR'];
341 }
Derek Jonesc5972282009-02-04 21:40:20 +0000342 elseif ($this->server('REMOTE_ADDR') AND $this->server('HTTP_CLIENT_IP'))
Derek Allard2067d1a2008-11-13 22:59:24 +0000343 {
344 $this->ip_address = $_SERVER['HTTP_CLIENT_IP'];
345 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000346 elseif ($this->server('HTTP_CLIENT_IP'))
347 {
348 $this->ip_address = $_SERVER['HTTP_CLIENT_IP'];
349 }
350 elseif ($this->server('HTTP_X_FORWARDED_FOR'))
351 {
352 $this->ip_address = $_SERVER['HTTP_X_FORWARDED_FOR'];
353 }
354
355 if ($this->ip_address === FALSE)
356 {
357 $this->ip_address = '0.0.0.0';
358 return $this->ip_address;
359 }
360
Robin Sowell76b369e2010-03-19 11:15:28 -0400361 if (strpos($this->ip_address, ',') !== FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000362 {
363 $x = explode(',', $this->ip_address);
Derek Jonesc5972282009-02-04 21:40:20 +0000364 $this->ip_address = trim(end($x));
Derek Allard2067d1a2008-11-13 22:59:24 +0000365 }
366
367 if ( ! $this->valid_ip($this->ip_address))
368 {
369 $this->ip_address = '0.0.0.0';
370 }
371
372 return $this->ip_address;
373 }
374
375 // --------------------------------------------------------------------
376
377 /**
378 * Validate IP Address
379 *
380 * Updated version suggested by Geert De Deckere
Barry Mienydd671972010-10-04 16:33:58 +0200381 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000382 * @access public
383 * @param string
Bo-Yi Wu013c8952011-09-12 15:03:44 +0800384 * @return bool
Derek Allard2067d1a2008-11-13 22:59:24 +0000385 */
Bo-Yi Wu4db872f2011-09-12 10:52:37 +0800386 public function valid_ip($ip)
Derek Allard2067d1a2008-11-13 22:59:24 +0000387 {
Bo-Yi Wuc9f84c12011-09-12 10:45:39 +0800388 // if php version >= 5.2, use filter_var to check validate ip.
Bo-Yi Wu47213792011-09-13 22:44:07 +0800389 if (function_exists('filter_var'))
Bo-Yi Wuc9f84c12011-09-12 10:45:39 +0800390 {
391 return (bool) filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4);
392 }
393
Derek Allard2067d1a2008-11-13 22:59:24 +0000394 $ip_segments = explode('.', $ip);
395
396 // Always 4 segments needed
397 if (count($ip_segments) != 4)
398 {
399 return FALSE;
400 }
401 // IP can not start with 0
402 if ($ip_segments[0][0] == '0')
403 {
404 return FALSE;
405 }
406 // Check each segment
407 foreach ($ip_segments as $segment)
408 {
Barry Mienydd671972010-10-04 16:33:58 +0200409 // IP segments must be digits and can not be
Derek Allard2067d1a2008-11-13 22:59:24 +0000410 // longer than 3 digits or greater then 255
411 if ($segment == '' OR preg_match("/[^0-9]/", $segment) OR $segment > 255 OR strlen($segment) > 3)
412 {
413 return FALSE;
414 }
415 }
416
417 return TRUE;
418 }
419
420 // --------------------------------------------------------------------
421
422 /**
423 * User Agent
424 *
425 * @access public
426 * @return string
427 */
Bo-Yi Wu4db872f2011-09-12 10:52:37 +0800428 public function user_agent()
Derek Allard2067d1a2008-11-13 22:59:24 +0000429 {
430 if ($this->user_agent !== FALSE)
431 {
432 return $this->user_agent;
433 }
434
435 $this->user_agent = ( ! isset($_SERVER['HTTP_USER_AGENT'])) ? FALSE : $_SERVER['HTTP_USER_AGENT'];
436
437 return $this->user_agent;
438 }
439
440 // --------------------------------------------------------------------
441
442 /**
Derek Jones69fc4fc2010-03-02 13:36:31 -0600443 * Sanitize Globals
Derek Allard2067d1a2008-11-13 22:59:24 +0000444 *
Derek Jones69fc4fc2010-03-02 13:36:31 -0600445 * This function does the following:
446 *
447 * Unsets $_GET data (if query strings are not enabled)
448 *
449 * Unsets all globals if register_globals is enabled
450 *
451 * Standardizes newline characters to \n
452 *
453 * @access private
454 * @return void
Derek Allard2067d1a2008-11-13 22:59:24 +0000455 */
Bo-Yi Wu4db872f2011-09-12 10:52:37 +0800456 private function _sanitize_globals()
Derek Allard2067d1a2008-11-13 22:59:24 +0000457 {
Derek Jones69fc4fc2010-03-02 13:36:31 -0600458 // It would be "wrong" to unset any of these GLOBALS.
David Behler9b5df592011-08-14 21:04:17 +0200459 $protected = array('_SERVER', '_GET', '_POST', '_FILES', '_REQUEST',
Greg Akerec2f5712010-11-15 16:22:12 -0600460 '_SESSION', '_ENV', 'GLOBALS', 'HTTP_RAW_POST_DATA',
David Behler9b5df592011-08-14 21:04:17 +0200461 'system_folder', 'application_folder', 'BM', 'EXT',
Greg Akerec2f5712010-11-15 16:22:12 -0600462 'CFG', 'URI', 'RTR', 'OUT', 'IN');
Derek Allard2067d1a2008-11-13 22:59:24 +0000463
Barry Mienydd671972010-10-04 16:33:58 +0200464 // Unset globals for securiy.
Derek Jones69fc4fc2010-03-02 13:36:31 -0600465 // This is effectively the same as register_globals = off
466 foreach (array($_GET, $_POST, $_COOKIE) as $global)
Derek Allard2067d1a2008-11-13 22:59:24 +0000467 {
Derek Jones69fc4fc2010-03-02 13:36:31 -0600468 if ( ! is_array($global))
Derek Allard2067d1a2008-11-13 22:59:24 +0000469 {
Derek Jones69fc4fc2010-03-02 13:36:31 -0600470 if ( ! in_array($global, $protected))
471 {
472 global $$global;
473 $$global = NULL;
474 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000475 }
Derek Jones69fc4fc2010-03-02 13:36:31 -0600476 else
477 {
478 foreach ($global as $key => $val)
479 {
480 if ( ! in_array($key, $protected))
481 {
482 global $$key;
483 $$key = NULL;
484 }
485 }
486 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000487 }
488
Derek Jones69fc4fc2010-03-02 13:36:31 -0600489 // Is $_GET data allowed? If not we'll set the $_GET to an empty array
490 if ($this->_allow_get_array == FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000491 {
Derek Jones69fc4fc2010-03-02 13:36:31 -0600492 $_GET = array();
Derek Allard2067d1a2008-11-13 22:59:24 +0000493 }
494 else
495 {
Derek Jones69fc4fc2010-03-02 13:36:31 -0600496 if (is_array($_GET) AND count($_GET) > 0)
Derek Allard2067d1a2008-11-13 22:59:24 +0000497 {
Pascal Kriete5d5895f2011-02-14 13:27:07 -0500498 foreach ($_GET as $key => $val)
Derek Jones69fc4fc2010-03-02 13:36:31 -0600499 {
500 $_GET[$this->_clean_input_keys($key)] = $this->_clean_input_data($val);
501 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000502 }
503 }
504
Derek Jones69fc4fc2010-03-02 13:36:31 -0600505 // Clean $_POST Data
506 if (is_array($_POST) AND count($_POST) > 0)
Derek Allard2067d1a2008-11-13 22:59:24 +0000507 {
Pascal Kriete5d5895f2011-02-14 13:27:07 -0500508 foreach ($_POST as $key => $val)
Derek Jones69fc4fc2010-03-02 13:36:31 -0600509 {
510 $_POST[$this->_clean_input_keys($key)] = $this->_clean_input_data($val);
511 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000512 }
513
Derek Jones69fc4fc2010-03-02 13:36:31 -0600514 // Clean $_COOKIE Data
515 if (is_array($_COOKIE) AND count($_COOKIE) > 0)
Derek Allard2067d1a2008-11-13 22:59:24 +0000516 {
Derek Jones69fc4fc2010-03-02 13:36:31 -0600517 // Also get rid of specially treated cookies that might be set by a server
518 // or silly application, that are of no use to a CI application anyway
519 // but that when present will trip our 'Disallowed Key Characters' alarm
520 // http://www.ietf.org/rfc/rfc2109.txt
521 // note that the key names below are single quoted strings, and are not PHP variables
522 unset($_COOKIE['$Version']);
523 unset($_COOKIE['$Path']);
524 unset($_COOKIE['$Domain']);
525
Pascal Kriete5d5895f2011-02-14 13:27:07 -0500526 foreach ($_COOKIE as $key => $val)
Derek Jones69fc4fc2010-03-02 13:36:31 -0600527 {
528 $_COOKIE[$this->_clean_input_keys($key)] = $this->_clean_input_data($val);
529 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000530 }
531
Derek Jones69fc4fc2010-03-02 13:36:31 -0600532 // Sanitize PHP_SELF
533 $_SERVER['PHP_SELF'] = strip_tags($_SERVER['PHP_SELF']);
534
535
536 // CSRF Protection check
537 if ($this->_enable_csrf == TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000538 {
Derek Jones69fc4fc2010-03-02 13:36:31 -0600539 $this->security->csrf_verify();
Derek Allard2067d1a2008-11-13 22:59:24 +0000540 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000541
Derek Jones69fc4fc2010-03-02 13:36:31 -0600542 log_message('debug', "Global POST and COOKIE data sanitized");
Derek Allard2067d1a2008-11-13 22:59:24 +0000543 }
544
545 // --------------------------------------------------------------------
546
547 /**
Derek Jones69fc4fc2010-03-02 13:36:31 -0600548 * Clean Input Data
Derek Allard2067d1a2008-11-13 22:59:24 +0000549 *
Derek Jones69fc4fc2010-03-02 13:36:31 -0600550 * This is a helper function. It escapes data and
551 * standardizes newline characters to \n
Derek Allard2067d1a2008-11-13 22:59:24 +0000552 *
553 * @access private
554 * @param string
Derek Allard2067d1a2008-11-13 22:59:24 +0000555 * @return string
556 */
Bo-Yi Wu4db872f2011-09-12 10:52:37 +0800557 private function _clean_input_data($str)
Derek Allard2067d1a2008-11-13 22:59:24 +0000558 {
Derek Jones69fc4fc2010-03-02 13:36:31 -0600559 if (is_array($str))
Derek Allard2067d1a2008-11-13 22:59:24 +0000560 {
Derek Jones69fc4fc2010-03-02 13:36:31 -0600561 $new_array = array();
562 foreach ($str as $key => $val)
563 {
564 $new_array[$this->_clean_input_keys($key)] = $this->_clean_input_data($val);
565 }
566 return $new_array;
Derek Allard2067d1a2008-11-13 22:59:24 +0000567 }
568
Andrey Andreevaf728622011-10-20 10:11:59 +0300569 /* We strip slashes if magic quotes is on to keep things consistent
570
571 NOTE: In PHP 5.4 get_magic_quotes_gpc() will always return 0 and
572 it will probably not exist in future versions at all.
573 */
574 if ( ! is_php('5.4') && get_magic_quotes_gpc())
Derek Allard2067d1a2008-11-13 22:59:24 +0000575 {
Derek Jones69fc4fc2010-03-02 13:36:31 -0600576 $str = stripslashes($str);
577 }
578
579 // Clean UTF-8 if supported
580 if (UTF8_ENABLED === TRUE)
581 {
582 $str = $this->uni->clean_string($str);
583 }
David Behler9b5df592011-08-14 21:04:17 +0200584
Pascal Kriete14a0ac62011-04-05 14:55:56 -0400585 // Remove control characters
586 $str = remove_invisible_characters($str);
Derek Jones69fc4fc2010-03-02 13:36:31 -0600587
588 // Should we filter the input data?
589 if ($this->_enable_xss === TRUE)
590 {
591 $str = $this->security->xss_clean($str);
592 }
593
594 // Standardize newlines if needed
595 if ($this->_standardize_newlines == TRUE)
596 {
597 if (strpos($str, "\r") !== FALSE)
598 {
Phil Sturgeon82f9b152011-03-16 22:18:08 +0000599 $str = str_replace(array("\r\n", "\r", "\r\n\n"), PHP_EOL, $str);
Derek Jones69fc4fc2010-03-02 13:36:31 -0600600 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000601 }
602
603 return $str;
604 }
605
606 // --------------------------------------------------------------------
607
608 /**
Derek Jones69fc4fc2010-03-02 13:36:31 -0600609 * Clean Keys
Derek Allard2067d1a2008-11-13 22:59:24 +0000610 *
Derek Jones69fc4fc2010-03-02 13:36:31 -0600611 * This is a helper function. To prevent malicious users
612 * from trying to exploit keys we make sure that keys are
613 * only named with alpha-numeric text and a few other items.
Derek Allard2067d1a2008-11-13 22:59:24 +0000614 *
Derek Jones69fc4fc2010-03-02 13:36:31 -0600615 * @access private
Derek Allard2067d1a2008-11-13 22:59:24 +0000616 * @param string
617 * @return string
618 */
Bo-Yi Wu4db872f2011-09-12 10:52:37 +0800619 private function _clean_input_keys($str)
Derek Allard2067d1a2008-11-13 22:59:24 +0000620 {
Derek Jones69fc4fc2010-03-02 13:36:31 -0600621 if ( ! preg_match("/^[a-z0-9:_\/-]+$/i", $str))
Derek Allard2067d1a2008-11-13 22:59:24 +0000622 {
Derek Jones69fc4fc2010-03-02 13:36:31 -0600623 exit('Disallowed Key Characters.');
Derek Allard2067d1a2008-11-13 22:59:24 +0000624 }
625
Derek Jones69fc4fc2010-03-02 13:36:31 -0600626 // Clean UTF-8 if supported
627 if (UTF8_ENABLED === TRUE)
628 {
629 $str = $this->uni->clean_string($str);
630 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000631
Derek Jones69fc4fc2010-03-02 13:36:31 -0600632 return $str;
633 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000634
Greg Akerec2f5712010-11-15 16:22:12 -0600635 // --------------------------------------------------------------------
636
637 /**
638 * Request Headers
639 *
David Behler9b5df592011-08-14 21:04:17 +0200640 * In Apache, you can simply call apache_request_headers(), however for
Greg Akerec2f5712010-11-15 16:22:12 -0600641 * people running other webservers the function is undefined.
642 *
Bo-Yi Wu4db872f2011-09-12 10:52:37 +0800643 * @access public
David Behlercda768a2011-08-14 23:52:48 +0200644 * @param bool XSS cleaning
645 *
Greg Akerec2f5712010-11-15 16:22:12 -0600646 * @return array
647 */
648 public function request_headers($xss_clean = FALSE)
649 {
650 // Look at Apache go!
651 if (function_exists('apache_request_headers'))
652 {
653 $headers = apache_request_headers();
654 }
655 else
656 {
657 $headers['Content-Type'] = (isset($_SERVER['CONTENT_TYPE'])) ? $_SERVER['CONTENT_TYPE'] : @getenv('CONTENT_TYPE');
658
659 foreach ($_SERVER as $key => $val)
660 {
661 if (strncmp($key, 'HTTP_', 5) === 0)
662 {
663 $headers[substr($key, 5)] = $this->_fetch_from_array($_SERVER, $key, $xss_clean);
664 }
665 }
666 }
667
668 // take SOME_HEADER and turn it into Some-Header
669 foreach ($headers as $key => $val)
670 {
671 $key = str_replace('_', ' ', strtolower($key));
672 $key = str_replace(' ', '-', ucwords($key));
David Behler9b5df592011-08-14 21:04:17 +0200673
Greg Akerec2f5712010-11-15 16:22:12 -0600674 $this->headers[$key] = $val;
675 }
David Behler9b5df592011-08-14 21:04:17 +0200676
Greg Akerec2f5712010-11-15 16:22:12 -0600677 return $this->headers;
678 }
679
680 // --------------------------------------------------------------------
681
682 /**
683 * Get Request Header
684 *
685 * Returns the value of a single member of the headers class member
686 *
Bo-Yi Wu4db872f2011-09-12 10:52:37 +0800687 * @access public
Greg Akerec2f5712010-11-15 16:22:12 -0600688 * @param string array key for $this->headers
689 * @param boolean XSS Clean or not
690 * @return mixed FALSE on failure, string on success
691 */
692 public function get_request_header($index, $xss_clean = FALSE)
693 {
694 if (empty($this->headers))
695 {
696 $this->request_headers();
697 }
David Behler9b5df592011-08-14 21:04:17 +0200698
Greg Akerec2f5712010-11-15 16:22:12 -0600699 if ( ! isset($this->headers[$index]))
700 {
701 return FALSE;
702 }
703
704 if ($xss_clean === TRUE)
705 {
Pascal Kriete14a0ac62011-04-05 14:55:56 -0400706 return $this->security->xss_clean($this->headers[$index]);
Greg Akerec2f5712010-11-15 16:22:12 -0600707 }
708
David Behler9b5df592011-08-14 21:04:17 +0200709 return $this->headers[$index];
Greg Akerec2f5712010-11-15 16:22:12 -0600710 }
711
Greg Aker081ac9d2010-11-22 14:42:53 -0600712 // --------------------------------------------------------------------
Phil Sturgeonc3828712011-01-19 12:31:47 +0000713
Greg Aker081ac9d2010-11-22 14:42:53 -0600714 /**
715 * Is ajax Request?
716 *
717 * Test to see if a request contains the HTTP_X_REQUESTED_WITH header
718 *
Bo-Yi Wu4db872f2011-09-12 10:52:37 +0800719 * @access public
Phil Sturgeonc3828712011-01-19 12:31:47 +0000720 * @return boolean
Greg Aker081ac9d2010-11-22 14:42:53 -0600721 */
722 public function is_ajax_request()
723 {
Greg Aker2fae66e2010-12-09 15:49:34 -0600724 return ($this->server('HTTP_X_REQUESTED_WITH') === 'XMLHttpRequest');
Greg Aker081ac9d2010-11-22 14:42:53 -0600725 }
726
Phil Sturgeonc3828712011-01-19 12:31:47 +0000727 // --------------------------------------------------------------------
728
729 /**
730 * Is cli Request?
731 *
732 * Test to see if a request was made from the command line
733 *
Bo-Yi Wu4db872f2011-09-12 10:52:37 +0800734 * @access public
Phil Sturgeonc3828712011-01-19 12:31:47 +0000735 * @return boolean
736 */
737 public function is_cli_request()
738 {
Phil Sturgeonc5dccf72011-08-13 11:06:57 -0600739 return (php_sapi_name() == 'cli') or defined('STDIN');
Phil Sturgeonc3828712011-01-19 12:31:47 +0000740 }
741
Derek Allard2067d1a2008-11-13 22:59:24 +0000742}
743// END Input class
744
745/* End of file Input.php */
Phil Sturgeon33ed0f32011-02-16 19:03:49 +0000746/* Location: ./system/core/Input.php */