php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #16155 variables_order affects existence of php predefined variables
Submitted: 2002-03-18 18:18 UTC Modified: 2011-01-01 00:29 UTC
Votes:8
Avg. Score:4.8 ± 0.4
Reproduced:7 of 7 (100.0%)
Same Version:4 (57.1%)
Same OS:3 (42.9%)
From: rlm at pricegrabber dot com Assigned:
Status: Not a bug Package: *General Issues
PHP Version: 4CVS OS: all
Private report: No CVE-ID: None
 [2002-03-18 18:18 UTC] rlm at pricegrabber dot com
The entire point of "register_globals Off" is to provide a mechanism to disable automatic registration of EGPCS (Environment, Get, Post, Cookie, System) variables.  However, for this to be an effective strategy, scripts need access to these variables by other means.  This SHOULD be the HTTP_*_VARS and _GET[], _POST[], etc. variables.  But as of 4.1.2, track_vars (which is set on by default) doesn't work unless

(1) register_globals is set On, AND
(2) variables_order contains the particular type of variable you want.  That is, unless you set variables_order to contain "G", neither _GET[] nor HTTP_GET_VARS[] will be contain the results from the GET request, but if variables_order does contain "G", they *will*.

Considering the number of exploits caused by namespace pollution that register_globals has been accused (and convicted) of, this is about as serious a security bug as I can think of.  I will be digging through the source tree to come up with a patch.

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2002-03-18 23:03 UTC] rasmus@php.net
Uh, can anybody reproduce this?  I certainly can't.  HTTP_*_VARS are definitely on for me regardless of the register_globals setting.  I suspect user error here.
 [2002-03-18 23:27 UTC] rlm at pricegrabber dot com
Ah, I think I understand maybe why you can't replicate this.  In my /etc/httpd/conf/include.d directory (the entire dir is parsed by Apache on startup), I have a file that has the following lines in it, in the order following:

    php_value variables_order "es"
    php_flag register_globals Off

Remove the file containing these lines, and it works.  Install the file containing these lines, and it fails.
 [2002-03-19 10:19 UTC] rlm at pricegrabber dot com
No, it is a bug.  The problem is that if the configuration data comes from Apache rather than /etc/php.ini, the tracking variables aren't initialized correctly as described.
 [2002-03-19 11:42 UTC] rlm at pricegrabber dot com
To clarify:

1) There is no reason why variables_order should have any effect whatsoever on whether _GET, _POST, _COOKIE, or HTTP_*_VARS are set.  Ever.  Read the documentation on track_vars for why, but it certainly says they can be found WITHOUT mentioning any side effects of variables_order.  At the very least, this is a documentation bug.  At worst (and in reality) this is a violation of the "principle of least surprise"; that is, when does "can be found" not mean "can be found"?  What possible use could a programmer have for disabling EGPCS variable parsing to the extent of disabling _GET, _POST, etc.?

2) Even allowing for all the above, this should all work if the directives are in Apache.  It doesn't.
 [2002-03-19 18:56 UTC] rlm at pricegrabber dot com
I have confirmed this using just the /etc/php.ini file.  Unless variables_order is set for the corresponding variable, the superglobal doesn't get set.
 [2002-07-10 13:13 UTC] philip@php.net
This behavior is documented in various places and is expected.  When the variables_order documentation says "PHP will completely ignore them" it really means it.  There was talk of adding additional directives but nothing came of it (yet?).  See:

 http://marc.theaimsgroup.com/?l=php-dev&m=101194050211581
 http://marc.theaimsgroup.com/?l=php-dev&m=101194642021528
  
On a related note, track_vars doesn't do anything as of PHP 4.0.3. Also, even if variables_order lacks an E you can still use getenv() and the E info is still shown in phpinfo().  So I guess PHP never completely ignores E :)   
 [2002-07-10 13:46 UTC] rlm at pricegrabber dot com
In WHICH "various places" is this misbehavior documented?  And why is it NOT documented in the one place it should be mandatory -- the "track_vars" documentation?

http://www.php.net/manual/en/configuration.php#ini.track-vars

And finally -- since you brought it up -- why isn't track_vars functional obsolescence documented along with that variable?

I've said it before, and in this same bug -- this behavior amounts to poor design under the "least surprise" principle.
 [2002-07-10 14:09 UTC] philip@php.net
The various places are the: variables_order, register_globals, and predefind variables manual entries.

track_vars documentation states it's always on as of 4.0.3, do you feel this should be reworded?  I'll add a reference to variables_order there.

This bug remains open and I believe remains until a solution is found that doesn't affect BC.  Obviously some concern exists, see that thread.  There was a time when the register_globals directive didn't even exist.
 [2002-07-10 16:37 UTC] rlm at pricegrabber dot com
See my earlier comments but the possibility of the combination of track_vars=on and register_globals=off is entirely desirable.  That is, we want PHP to pick up variables from the URL, POST, cookies, etc. into HTTP_GET_VARS etc. WITHOUT importing them into the namespace.
 [2002-07-10 18:21 UTC] philip@php.net
Just set the PHP predefined variables you want in the  variables_order directive.  Like, GPCS or EGPCS.  And turn register_globals off.  This will do what you want.

I'm turning this into a feature request and changing the summary.  See Rasmus' post/thread for details on this request.

Whoever decided that variables_order should be 'es' during your install should be informed on the matter too.
 [2002-07-10 18:57 UTC] rlm at pricegrabber dot com
No, it won't, because that will also add the variables to the global namespace.  This is not a feature request -- it's *making the system work as advertised*.  There already is -- or should be, if the writers of the documentation were correct -- a way to disable global variable imports, which ought to be the configuration lines

register_globals = Off
variables_order = ""

That is,

   - register_globals should control the registration of globals, and
   - variables_order should control the source(s) of and order of global variable parsing.

Just like it says in the documentation:

"variables_order string

Set the order of the EGPCS (Environment, GET, POST, Cookie, Server) variable parsing. The default setting of this directive is "EGPCS". Setting this to "GP", for example, will cause PHP to completely ignore environment variables, cookies and server variables, and to overwrite any GET method variables with POST-method variables of the same name."

Notice how the above makes NO mention of whether track_vars is set -- but that doesn't matter, because track_vars IS ALWAYS SET ON!  That implies that variable tracking in HTTP_*_VARS should ALWAYS happen.  ALWAYS.

The tools to do this already exists.  This is not a feature but a bug -- the extant documentation describes a rationally behaving environment, but PHP no longer conforms to it.
 [2002-07-10 20:08 UTC] philip@php.net
This is a feature request as it's documented and expected bahavior.  Your points are valid and shared by many.  It's a matter of sitting down, thinking it through, and coming up with a nice BC friendly solution.

In speaking with Zeev, he tentively suggested the following:
(a) Decouple variables_order from the $_* / $HTTP_*_VARS
    completely.
(b) Make it possible to prevent $_ENV and $_SERVER from
    being populated.  Like env_autoglobal = on and 
    server_autoglobal = on.
(c) It shouldn't be possible to prevent $_GET, $_POST,
    $_COOKIE, and $_FILES from being populated.

This falls in line with your suggestions.  The current variables_order manual entry is vague on this particular matter, yes, but it's there, and it's much clearer in the other aforementioned entries.
With variables_order = GPCS and register_globals = off, the global namespace will not be polluted.  Not sure what you mean there as $_GET['id'] will exist, $id will not.

 [2002-10-07 12:38 UTC] philip@php.net
feature request-> php options bug
 [2011-01-01 00:29 UTC] jani@php.net
-Status: Open +Status: Bogus -Package: Feature/Change Request +Package: *General Issues
 [2011-01-01 00:29 UTC] jani@php.net
Quite irrelevant request since there is no track_vars anymore. And lot of other means to access this stuff.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sun May 05 17:01:31 2024 UTC