blob: 744a2c934e9562d10686b9fc693405fe3a3c22f4 [file] [log] [blame]
Derek Jones8ede1a22011-10-05 13:34:52 -05001########
2Security
3########
4
5This page describes some "best practices" regarding web security, and
6details CodeIgniter's internal security features.
7
Andrey Andreev4bb2b952015-10-12 13:55:24 +03008.. note:: If you came here looking for a security contact, please refer to
9 our `Contribution Guide <../contributing/index>`.
10
Derek Jones8ede1a22011-10-05 13:34:52 -050011URI Security
12============
13
14CodeIgniter is fairly restrictive regarding which characters it allows
15in your URI strings in order to help minimize the possibility that
16malicious data can be passed to your application. URIs may only contain
17the following:
18
Andrey Andreev16a704c2012-11-09 17:25:00 +020019- Alpha-numeric text (latin characters only)
Derek Jones8ede1a22011-10-05 13:34:52 -050020- Tilde: ~
vlakoff4ad37082013-03-29 18:14:22 +010021- Percent sign: %
Derek Jones8ede1a22011-10-05 13:34:52 -050022- Period: .
23- Colon: :
24- Underscore: \_
25- Dash: -
vlakoff4ad37082013-03-29 18:14:22 +010026- Space
Derek Jones8ede1a22011-10-05 13:34:52 -050027
28Register_globals
Andrey Andreev1c6522c2015-01-21 23:12:13 +020029================
Derek Jones8ede1a22011-10-05 13:34:52 -050030
Andrey Andreev1c6522c2015-01-21 23:12:13 +020031During system initialization all global variables that are found to exist
32in the ``$_GET``, ``$_POST``, ``$_REQUEST`` and ``$_COOKIE`` are unset.
33
34The unsetting routine is effectively the same as *register_globals = off*.
Derek Jones8ede1a22011-10-05 13:34:52 -050035
Andrey Andreev16a704c2012-11-09 17:25:00 +020036display_errors
37==============
Derek Jones8ede1a22011-10-05 13:34:52 -050038
Andrey Andreev16a704c2012-11-09 17:25:00 +020039In production environments, it is typically desirable to "disable" PHP's
40error reporting by setting the internal *display_errors* flag to a value
Derek Jones8ede1a22011-10-05 13:34:52 -050041of 0. This disables native PHP errors from being rendered as output,
42which may potentially contain sensitive information.
43
purwandi89f6f1a2011-10-07 19:58:22 +070044Setting CodeIgniter's **ENVIRONMENT** constant in index.php to a value of
45**\'production\'** will turn off these errors. In development mode, it is
Derek Jones8ede1a22011-10-05 13:34:52 -050046recommended that a value of 'development' is used. More information
Andrey Andreev16a704c2012-11-09 17:25:00 +020047about differentiating between environments can be found on the
48:doc:`Handling Environments <environments>` page.
Derek Jones8ede1a22011-10-05 13:34:52 -050049
50magic_quotes_runtime
Andrey Andreev16a704c2012-11-09 17:25:00 +020051====================
Derek Jones8ede1a22011-10-05 13:34:52 -050052
Andrey Andreev16a704c2012-11-09 17:25:00 +020053The *magic_quotes_runtime* directive is turned off during system
Derek Jones8ede1a22011-10-05 13:34:52 -050054initialization so that you don't have to remove slashes when retrieving
55data from your database.
56
57**************
58Best Practices
59**************
60
61Before accepting any data into your application, whether it be POST data
62from a form submission, COOKIE data, URI data, XML-RPC data, or even
63data from the SERVER array, you are encouraged to practice this three
64step approach:
65
Derek Jones8ede1a22011-10-05 13:34:52 -050066#. Validate the data to ensure it conforms to the correct type, length,
Aaron Melocikdd6222b2015-06-18 08:40:43 -070067 size, etc.
Andrey Andreev1c6522c2015-01-21 23:12:13 +020068#. Filter the data as if it were tainted.
69#. Escape the data before submitting it into your database or outputting
70 it to a browser.
Derek Jones8ede1a22011-10-05 13:34:52 -050071
Andrey Andreev1c6522c2015-01-21 23:12:13 +020072CodeIgniter provides the following functions and tips to assist you
73in this process:
Derek Jones8ede1a22011-10-05 13:34:52 -050074
75XSS Filtering
76=============
77
78CodeIgniter comes with a Cross Site Scripting filter. This filter
Andrey Andreev16a704c2012-11-09 17:25:00 +020079looks for commonly used techniques to embed malicious JavaScript into
Derek Jones8ede1a22011-10-05 13:34:52 -050080your data, or other types of code that attempt to hijack cookies or
81do other malicious things. The XSS Filter is described
82:doc:`here <../libraries/security>`.
83
Andrey Andreev1c6522c2015-01-21 23:12:13 +020084.. note:: XSS filtering should *only be performed on output*. Filtering
85 input data may modify the data in undesirable ways, including
86 stripping special characters from passwords, which reduces
87 security instead of improving it.
88
89CSRF protection
90===============
91
92CSRF stands for Cross-Site Request Forgery, which is the process of an
93attacker tricking their victim into unknowingly submitting a request.
94
95CodeIgniter provides CSRF protection out of the box, which will get
96automatically triggered for every non-GET HTTP request, but also needs
97you to create your submit forms in a certain way. This is explained in
98the :doc:`Security Library <../libraries/security>` documentation.
99
100Password handling
Derek Jones8ede1a22011-10-05 13:34:52 -0500101=================
102
Andrey Andreev1c6522c2015-01-21 23:12:13 +0200103It is *critical* that you handle passwords in your application properly.
104
105Unfortunately, many developers don't know how to do that, and the web is
106full of outdated or otherwise wrongful advices, which doesn't help.
107
108We would like to give you a list of combined do's and don'ts to help you
109with that. Please read below.
110
111- DO NOT store passwords in plain-text format.
112
113 Always **hash** your passwords.
114
115- DO NOT use Base64 or similar encoding for storing passwords.
116
117 This is as good as storing them in plain-text. Really. Do **hashing**,
118 not *encoding*.
119
120 Encoding, and encryption too, are two-way processes. Passwords are
121 secrets that must only be known to their owner, and thus must work
122 only in one direction. Hashing does that - there's *no* un-hashing or
123 de-hashing, but there is decoding and decryption.
124
125- DO NOT use weak or broken hashing algorithms like MD5 or SHA1.
126
127 These algorithms are old, proven to be flawed, and not designed for
128 password hashing in the first place.
129
130 Also, DON'T invent your own algorithms.
131
132 Only use strong password hashing algorithms like BCrypt, which is used
133 in PHP's own `Password Hashing <http://php.net/password>`_ functions.
134
135 Please use them, even if you're not running PHP 5.5+, CodeIgniter
Andrey Andreeva8382792016-07-28 16:40:12 +0300136 provides them for you.
Andrey Andreevf1ca8652015-02-24 20:25:16 +0200137
Andrey Andreev1c6522c2015-01-21 23:12:13 +0200138- DO NOT ever display or send a password in plain-text format!
139
140 Even to the password's owner, if you need a "Forgotten password"
141 feature, just randomly generate a new, one-time (this is also important)
142 password and send that instead.
143
Andrey Andreeva8c499d2015-03-31 15:01:36 +0300144- DO NOT put unnecessary limits on your users' passwords.
Andrey Andreev1c6522c2015-01-21 23:12:13 +0200145
Andrey Andreeva8c499d2015-03-31 15:01:36 +0300146 If you're using a hashing algorithm other than BCrypt (which has a limit
147 of 72 characters), you should set a relatively high limit on password
148 lengths in order to mitigate DoS attacks - say, 1024 characters.
149
150 Other than that however, there's no point in forcing a rule that a
151 password can only be up to a number of characters, or that it can't
152 contain a certain set of special characters.
Andrey Andreev1c6522c2015-01-21 23:12:13 +0200153
154 Not only does this **reduce** security instead of improving it, but
155 there's literally no reason to do it. No technical limitations and
156 no (practical) storage constraints apply once you've hashed them, none!
157
158Validate input data
159===================
160
Andrey Andreev16a704c2012-11-09 17:25:00 +0200161CodeIgniter has a :doc:`Form Validation Library
162<../libraries/form_validation>` that assists you in
Derek Jones8ede1a22011-10-05 13:34:52 -0500163validating, filtering, and prepping your data.
164
Andrey Andreev1c6522c2015-01-21 23:12:13 +0200165Even if that doesn't work for your use case however, be sure to always
166validate and sanitize all input data. For example, if you expect a numeric
167string for an input variable, you can check for that with ``is_numeric()``
168or ``ctype_digit()``. Always try to narrow down your checks to a certain
169pattern.
170
171Have it in mind that this includes not only ``$_POST`` and ``$_GET``
172variables, but also cookies, the user-agent string and basically
173*all data that is not created directly by your own code*.
174
175
Derek Jones8ede1a22011-10-05 13:34:52 -0500176Escape all data before database insertion
177=========================================
178
179Never insert information into your database without escaping it.
Andrey Andreev16a704c2012-11-09 17:25:00 +0200180Please see the section that discusses :doc:`database queries
181<../database/queries>` for more information.
Derek Jones8ede1a22011-10-05 13:34:52 -0500182
Andrey Andreev16a704c2012-11-09 17:25:00 +0200183Hide your files
184===============
Derek Jones8ede1a22011-10-05 13:34:52 -0500185
Andrey Andreev16a704c2012-11-09 17:25:00 +0200186Another good security practice is to only leave your *index.php*
187and "assets" (e.g. .js, css and image files) under your server's
188*webroot* directory (most commonly named "htdocs/"). These are
189the only files that you would need to be accessible from the web.
190
191Allowing your visitors to see anything else would potentially
192allow them to access sensitive data, execute scripts, etc.
193
194If you're not allowed to do that, you can try using a .htaccess
195file to restrict access to those resources.
196
197CodeIgniter will have an index.html file in all of its
198directories in an attempt to hide some of this data, but have
199it in mind that this is not enough to prevent a serious
Aaron Melocikdd6222b2015-06-18 08:40:43 -0700200attacker.