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.
Try Implementing
register_globals
on servers where it has been disabled or removed
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 false
is true
and passes the if
check) to access /highly/sensitive/data.php
.
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.
The constant 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;
- Turn
ON
all PHP Notices, Warnings and Errors in the development usingerror_reporting(E_ALL|E_STRICT);
. When you move your code to production server, replace the above line witherror_reporting(0); ini_set('display_errors','0');
. As of PHP 5.4,E_ALL
includesE_STRICT
, so it is sufficient to useerror_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.