PHP register globals

 

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.
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…

Input string : ‘; TRUNCATE some_table;
Filter output : &#39;; TRUNCATE some_table;

By encoding the quote the resultant o/p cannot be used in an injection attack.



 Leave a Reply

(required)

(required)