summaryrefslogtreecommitdiffstats
path: root/user_guide_src/source/libraries/security.rst
blob: 27e6e561b2d637d0cebea05f2b135a0df3cedfa2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
##############
Security Class
##############

The Security Class contains methods that help you create a secure
application, processing input data for security.

.. contents::
  :local:

.. raw:: html

  <div class="custom-index container"></div>

*************
XSS Filtering
*************

CodeIgniter comes with a Cross Site Scripting Hack prevention filter
which can either run automatically to filter all POST and COOKIE data
that is encountered, or you can run it on a per item basis. By default
it does **not** run globally since it requires a bit of processing
overhead, and since you may not need it in all cases.

The XSS filter looks for commonly used techniques to trigger Javascript
or other types of code that attempt to hijack cookies or do other
malicious things. If anything disallowed is encountered it is rendered
safe by converting the data to character entities.

Note: This function should only be used to deal with data upon
submission. It's not something that should be used for general runtime
processing since it requires a fair amount of processing overhead.

To filter data through the XSS filter use the ``xss_clean()`` method::

	$data = $this->security->xss_clean($data);

If you want the filter to run automatically every time it encounters
POST or COOKIE data you can enable it by opening your
application/config/config.php file and setting this::

	$config['global_xss_filtering'] = TRUE;

.. note:: If you use the form validation class, it gives you the option of
	XSS filtering as well.

An optional second parameter, *is_image*, allows this function to be used
to test images for potential XSS attacks, useful for file upload
security. When this second parameter is set to TRUE, instead of
returning an altered string, the function returns TRUE if the image is
safe, and FALSE if it contained potentially malicious information that a
browser may attempt to execute.

::

	if ($this->security->xss_clean($file, TRUE) === FALSE)
	{
		// file failed the XSS test
	}

*********************************
Cross-site request forgery (CSRF)
*********************************

You can enable CSRF protection by altering your **application/config/config.php**
file in the following way::

	$config['csrf_protection'] = TRUE;

If you use the :doc:`form helper <../helpers/form_helper>`, then
:func:`form_open()` will automatically insert a hidden csrf field in
your forms. If not, then you can use ``get_csrf_token_name()``
and ``get_csrf_hash()``
::

	$csrf = array(
		'name' => $this->security->get_csrf_token_name(),
		'hash' => $this->security->get_csrf_hash()
	);

	...

	<input type="hidden" name="<?=$csrf['name'];?>" value="<?=$csrf['hash'];?>" />

Tokens may be either regenerated on every submission (default) or
kept the same throughout the life of the CSRF cookie. The default
regeneration of tokens provides stricter security, but may result
in usability concerns as other tokens become invalid (back/forward
navigation, multiple tabs/windows, asynchronous actions, etc). You
may alter this behavior by editing the following config parameter

::

	$config['csrf_regeneration'] = TRUE;

Select URIs can be whitelisted from csrf protection (for example API
endpoints expecting externally POSTed content). You can add these URIs
by editing the 'csrf_exclude_uris' config parameter::

	$config['csrf_exclude_uris'] = array('api/person/add');

Regular expressions are also supported (case-insensitive)::

	$config['csrf_exclude_uris'] = array(
		'api/record/[0-9]+',
		'api/title/[a-z]+'
	);

***************
Class Reference
***************

.. php:class:: CI_Security

	.. php:method:: xss_clean($str[, $is_image = FALSE])

		:param	mixed	$str: Input string or an array of strings
		:returns:	XSS-clean data
		:rtype:	mixed

		Tries to remove XSS exploits from the input data and returns the cleaned string.
		If the optional second parameter is set to true, it will return boolean TRUE if the image is safe to use and FALSE if malicious data was detected in it.

	.. php:method:: sanitize_filename($str[, $relative_path = FALSE])

		:param	string	$str: File name/path
		:param	bool	$relative_path: Whether to preserve any directories in the file path
		:returns:	Sanitized file name/path
		:rtype:	string

		Tries to sanitize filenames in order to prevent directory traversal attempts
		and other security threats, which is particularly useful for files that were supplied via user input.
		::

			$filename = $this->security->sanitize_filename($this->input->post('filename'));

		If it is acceptable for the user input to include relative paths, e.g.
		*file/in/some/approved/folder.txt*, you can set the second optional parameter, ``$relative_path`` to TRUE.
		::

			$filename = $this->security->sanitize_filename($this->input->post('filename'), TRUE);

	.. php:method:: get_csrf_token_name()

		:returns:	CSRF token name
		:rtype:	string

		Returns the CSRF token name (the ``$config['csrf_token_name']`` value).

	.. php:method:: get_csrf_hash()

		:returns:	CSRF hash
		:rtype:	string

		Returns the CSRF hash value. Useful in combination with ``get_csrf_token_name()``
		for manually building forms or sending valid AJAX POST requests.

	.. php:method:: entity_decode($str[, $charset = NULL])

		:param	string	$str: Input string
		:param	string	$charset: Character set of the input string
		:returns:	Entity-decoded string
		:rtype:	string

		This method acts a lot like PHP's own native ``html_entity_decode()`` function in ENT_COMPAT mode, only
		it tries to detect HTML entities that don't end in a semicolon because some browsers allow that.

		If the ``$charset`` parameter is left empty, then your configured ``$config['charset']`` value will be used.

	.. php:method:: get_random_bytes($length)

		:param	int	$length: Output length
		:returns:	A binary stream of random bytes or FALSE on failure
		:rtype:	string

		A convenience method for getting proper random bytes via ``mcrypt_create_iv()``,
		``/dev/urandom`` or ``openssl_random_pseudo_bytes()`` (in that order), if one
		of them is available.

		Used for generating CSRF and XSS tokens.

		.. note:: The output is NOT guaranteed to be cryptographically secure,
			just the best attempt at that.