turn register_globals off on cgi PHP installs (non Apache Module)

Hello guys,

I really need to have register_globals switched off on my site and my host has it switched on. I realise that if the host has PHP installed as an Apache module then I can switch it off via a .htaccess file on a per-site basis. However, my host uses the cgi implementation of PHP therefore I do not have a valid method of turning this setting off.

Any ideas how I can get around this?

Thanks
jonlondon12Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Richard QuadlingSenior Software DeveloperCommented:
Hmm.

Not easily.

The register globals option occurs BEFORE your script is executed, so by the time the script starts you already have the array populated.

But, you could do some cleaning.

All you need to do is to protect the super globals.

$_FILES, $_COOKIE, $_POST, $_GET, $_SERVER, $_ENV, $_SESSION.

The $_REQUEST is, in effect, an amalgum of some of the above (depending upon the server setup).

$GLOBALS is the global array.

So, you could do something like this ...

<?php
// Remove ALL non super global variables.
foreach($GLOBALS as $s_variable_name => $m_variable_value)
 {
 if (!in_array(array('_FILES', '_COOKIE', '_POST', '_GET', '_SERVER', '_ENV', '_SESSION'))
  {
  unset($GLOBALS[$s_variable_name]);
  }
 }
// Continue with your script.
?>

0
Richard QuadlingSenior Software DeveloperCommented:
Ok.

This will need extending to include (maybe), argv and argc, if a CGI or CLI environment is also supported.

Also, if you use an auto_prepend_file or auto_append_file entry in .htaccess / php.ini then you will need to exclude any variables you use there too.

On my machine ...

<?php
foreach($GLOBALS as $s_name => $m_value)
 {
 echo "$s_name\n";
 }
?>

GLOBALS
_ENV
argv
argc
_POST
_GET
_COOKIE
_SERVER
_FILES
_REQUEST
am_default_context
r_default_context
m_value
s_name


0
Richard QuadlingSenior Software DeveloperCommented:
Bloody hell. I'm a ZCE and somehow, today, I'm supplying BAD code.

Sorry.

Ok. Here is a TESTED example.

<?php
// Define a junk variable.
$s_junk = 'Something from register_globals maybe.';

// See what GLOBALS contains.
echo "Before\n";
foreach($GLOBALS as $s_name => $m_value)
 {
 echo "$s_name\n";
 }

// Remove ALL non super global variables.
foreach($GLOBALS as $s_variable_name => $m_variable_value)
 {
 if (!in_array($s_variable_name, array('GLOBALS', 'argv', 'argc', '_FILES', '_COOKIE', '_POST', '_GET', '_SERVER', '_ENV', '_SESSION', 's_variable_name', 'm_variable_value')))
  {
  unset($GLOBALS[$s_variable_name]);
  }
 }
unset($GLOBALS['s_variable_name']);
unset($GLOBLAS('m_variable_value']);

// See what GLOBALS contains.
echo "\n\nAfter\n";
foreach($GLOBALS as $s_name => $m_value)
 {
 echo "$s_name\n";
 }

?>

This produces output of ...

Before
GLOBALS
_ENV
argv
argc
_POST
_GET
_COOKIE
_SERVER
_FILES
_REQUEST
am_default_context <<<< For me, this should be protected as it is the data array for my global default context to route PHP fopen() through the proxy server.
r_default_context <<<< For me, this should be protected as it is the global default context to route PHP fopen() through the proxy server.
s_junk <<<<< Should be missing after the clean up.
m_value <<<< Used to show the BEFORE
s_name <<<< User to show the BEFORE


After
GLOBALS
_ENV
argv
argc
_POST
_GET
_COOKIE
_SERVER
_FILES
m_value <<<< Used to show the AFTER
s_name <<<< Used to show the AFTER

0
Cloud Class® Course: SQL Server Core 2016

This course will introduce you to SQL Server Core 2016, as well as teach you about SSMS, data tools, installation, server configuration, using Management Studio, and writing and executing queries.

jonlondon12Author Commented:
Hey Thanks Richard, thats a lot of help you've given me and it's much appreciated.

The main reason I need register_globals switched off is because I believe it is this setting that is giving me problems accessing objects that are stored in sessions.

For example,

            $_SESSION['page']=unserialize($_SESSION['page']);
            $pageName=$_SESSION['page']->getName();
            $windowTitle=$_SESSION['page']->getWindowTitle();
            $HTML=$_SESSION['page']->getContent();
            $_SESSION['page']=serialize($_SESSION['page']);

gives the following error:

Fatal error: Call to a member function on a non-object

This is not a problem on my local test machine where register_globals are switched off.
0
Richard QuadlingSenior Software DeveloperCommented:
This is in the PHP Manual on "Serializing objects - objects in sessions" ...

"If you are using sessions and use session_register() to register objects, these objects are serialized automatically at the end of each PHP page, and are unserialized automatically on each of the following pages. This basically means that these objects can show up on any of your pages once they become part of your session.

It is strongly recommended that you include the class definitions of all such registered objects on all of your pages, even if you do not actually use these classes on all of your pages. If you don't and an object is being unserialized without its class definition being present, it will lose its class association and become an object of class stdClass without any functions available at all, that is, it will become quite useless.

So if in the example above $a became part of a session by running session_register("a"), you should include the file classa.inc on all of your pages, not only page1.php and page2.php."

You've probably read this, but it is still worth repeating, just in case you are not familair with it.

Personally, I would NOT ...

$_SESSION['page']=unserialize($_SESSION['page']);

I would ...

$o_class_name_here_and_instance_name_here = unserialize($_SESSION['page']);

e.g..

$o_page_current = unserialize($_SESSION['page']);

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Richard QuadlingSenior Software DeveloperCommented:
By using an __autoload() function you can remove the necessity of including all the require/include_once()'s in your code.

Take a look at my user notes on __autoload http://www.php.net/manual/en/language.oop5.autoload.php
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
PHP

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.