History
As is probably obvious from this site I don't earn my money coding websites.
I have coded up a number of sites over the years using self taught PHP and until I came across
the topic of support for REGISTER GLOBALS a couple of years or so back I had assumed that the
various request variables such as those in the $_SESSION $_COOKIE $_POST and $_GET associative
arrays just became automatically available to a PHP script and that was how it worked. Come to
that I'm not even certain I was aware of the global arrays at all. Anyway the last time my
hoster changed servers I found that nothing was working on the new server because support
for REGISTER GLOBALS was off. I read up about the security risks and decided at that time
to take the chance and got my hoster to turn support on.
Biting the Bullet
Another server move in September 2008 and the same problem cropped up again. After reading up
on the issue again I found that support for REGISTER GLOBALS would eventually be removed
entirely from PHP so decided to bite the bullet and recode my sites. This was pretty trivial
for DigitalHam but I also have some more complex sites. Worst of all a complex site based on
a script I downloaded and modified so 70% of the code was completely unfamiliar to me. Now
coding up a site from scratch which doesn't rely on REGISTER GLOBALS is no big deal but wading
through oodles of code to retrofit the necessary variable extraction is no fun at all so I
decided to have the computer help me out. Hopefully my cheat may also assist others.
Script to assist recoding for REGISTER GLOBALS OFF
By adding the following script at the start of your page you can ensure it works and also
display the code necessary to make it work without the risk of passing all request variables
into your script (the risks of doing so are precisely why support for REGISTER GLOBALS is
being dropped). As a bonus the variables will also get sanitized by the built in PHP filter
to remove the risk of script kiddies using SQL injection to screw up any SQL database you may
have.
Code to insert in your script
<?php
// Put this right at the start of the script but after any session_start();
$debug_fix = 1;
include ("debug.php");
?>
<?php
// Put this after your <body> tag
if ($debug) echo "<br>$debug<br>";
?>
Content of debug.php
<?php
$debug = "";
if ($debug_fix)
{
foreach($_SESSION as $__k => $__v)
{
if (!isset($$__k))
{
if ($debug_fix) $$__k = $__v;
$debug .= 'if (isset($_SESSION["'.$__k.'"])) $'.$__k.' = filter_var($_SESSION["'.$__k.'"], FILTER_SANITIZE_STRING); <br>';
}
}
foreach($_COOKIE as $__k => $__v)
{
if ((!isset($$__k)) && ($__k <> "PHPSESSID"))
{
if ($debug_fix) $$__k = $__v;
$debug .= 'if (isset($_COOKIE["'.$__k.'"])) $'.$__k.' = filter_var($_COOKIE["'.$__k.'"], FILTER_SANITIZE_STRING); <br>';
}
}
foreach($_POST as $__k => $__v)
{
if ((!isset($$__k)) && ($__k <> "PHPSESSID"))
{
if ($debug_fix) $$__k = $__v;
$debug .= 'if (isset($_POST["'.$__k.'"])) $'.$__k.' = filter_var($_POST["'.$__k.'"], FILTER_SANITIZE_STRING); <br>';
}
}
foreach($_GET as $__k => $__v)
{
if ((!isset($$__k)) && ($__k <> "PHPSESSID"))
{
if ($debug_fix) $$__k = $__v;
$debug .= 'if (isset($_GET["'.$__k.'"])) $'.$__k.' = filter_var($_GET["'.$__k.'"], FILTER_SANITIZE_STRING); <br>';
}
}
}
<?php
Notes on the script
To to use the script just add the portions as shown above to your various scripts. When you access
a script it will display code to pull the variables from the global arrays into your script. You
can copy the code from the page and paste it into your script. Be sure to access the script
from every link on your site and every page that uses it as an action for a form.
To disable the script without removing it completely just set $debug_fix = ''; This is handy when
you think you've completely tested the script but aren't 100% certain. Obviously once you are
certain the debugging code should just be removed.
Just because a COOKIE variable is shown it doesn't necessarily mean your script actually uses it
- it may be appearing because you have a cookie which some other script in your site created but
it is not used by the one you are working on - check the code.
Any given variable could be passed to your script as POST from one source and GET from another - unless you are
certain only GET or POST are ever used it may be easier to just use the $_REQUEST global arry which combines POST GET and COOKIE.
Notes on the script
The FILTER_SANITIZE_STRING is pretty much a sledgehammer - it could be that you cannot use it
or at least will need to specify some extra options. There are pleny of tutorials on its use
so I'll stick to showing what it does with a typical SQL injection attack...