Since the introduction of
register_globals feature in PHP, there was a lot of discussion around the web criticizing this feature as a security risk. There established a perception that all websites on servers having
register_globals enabled are insecure and vulnerable to hacking/injection. Consequently, the feature went to
Off in PHP 4.2, deprecated in PHP 5.3 and completely removed in PHP 5.4. Even before all this, many web hosts disabled this feature. This caused problems to those not-by-profession PHP coders who rely on ease of use of PHP language to code their business or personal website.
If you are one of those who think that
register_globals was insecure, then be prepared to consider PHP Variables and specially Constants equally insecure. I have something for you.
Below is an example code that demonstrates how a script may be compromised when
register_globals directive is turned
ON. The example was taken from php.net:
If the directive is
ON, an attacker can use
authorized query string variable with any value. Since anything other than
true and passes the
if check) to access
What caused this attack to be successful? Is it really
register_globals? Lets see.
Suppose we have PHP 5.4 where there is no
register_globals. The previous example (after slight change) and the one given below using constants can still be insecure.
If the user is authenticated one, the constant
AUTHORIZED will be defined as
true and later on user will be allowed access to highly sensitive data. But what if user is not legitimate? In that case, there will be no constant defined and PHP will issue the following notice:
Notice: Use of undefined constant AUTHORIZED – assumed ‘AUTHORIZED’ in /path/to/www/dir/script.php on line 12.
AUTHORIZED will be assumed by PHP as a string
"AUTHORIZED" that will evaluate to
true when casted to
bool by PHP, resulting in everyone to pass the
if( AUTHORIZED ) check, as it is the way PHP works.
User was not authorized to get access to restricted areas, but the script let it do. There was no
register_globals, but the same sample script is still insecure. So, where the problem is?
The problem lies in Bad Coding Practices.
PHP does not require you to initialize variables before using (but it does not mean that you do not have to). However, if you try to use an uninitialized variable, PHP treats it as
null and issues a “Notice” that the variable is undefined. On the other hand, undefined constants are treated by PHP as
string and a “Notice” is issued.
To avoid such problems, what a PHP developer needs to do is:
- Make sure that variables are always initialized and constant always defined before they are used;
ONall PHP Notices, Warnings and Errors in the development using
error_reporting(E_ALL|E_STRICT);. When you move your code to production server, replace the above line with
error_reporting(0); ini_set('display_errors','0');. As of PHP 5.4,
E_STRICT, so it is sufficient to use
error_reporting(E_ALL);on development servers that have PHP 5.4+.
The secure authentication script should look like:
Or, with constant:
Properly initializing variables with very strict error reporting always benefits you. It not only improves you coding skills, but also makes your code more secure and reliable. There was no security problem with
register_globals but the ease of use of PHP combined with poor coding practices adopted by coders lead it to become a security threat, causing it to die even when it was still needed. Now when
register_globals is officially dead, your code is still no more secure and even your variables and constants can harm your script depending upon how you use them.