<?php
echo "test";
echo $city;
?>
This keeps echoing out the city from the url even though there is no other code
on the page.
I am assuming this is a global variable...
<?php
unset($GLOBALS[_SERVER]);
echo $city;
?>
I have started and destroyed a session to make sure is is not in a session.
If I change the variable it will not echo out.
If I change the url ?city=Boston to ?city=Chicago then it updates.
$city = $_GET["city"]; does not exist on the page...the rest of the page is empty.
The behavior that you're describing sounds like the PHP register_globals configuration option is enabled. This option causes all GET and POST variables (as well as optionally cookies) to be created as global variables during script startup. This is a huge security issue, and as such has defaulted to being off since PHP 4.2.0 (released April 2002), and cannot be enabled at all in PHP 5.4 and later (released March 2012). The fact that it's on for your system is troubling, as it indicates that you are running PHP 5.3 or earlier, which is no longer receiving security patches!
To disable it, upgrade PHP to a supported version.
If this is not possible, edit your PHP configuration file, find the line where register_globals = On (or = 1) is being set, and remove it. This option has not been recommended for well over a decade; it should not be enabled.
(There is no safe way to disable register_globals at runtime. Disabling it using ini_set() doesn't work, as it takes effect before the script starts, and there is no way to safely remove all of the variables it creates, as it's sometimes possible for these variables to overwrite system globals. The only safe approach is to turn it off entirely.)
Most likely reason for $city already having a value is register_globals setting being ON. What it means that every GET, POST and some other variables are registered as global variables in your script. For example, if you open your script like script.php?city=New+York, you will have a variable $city defined in your code with value "New York".
If you don't want that behavior, you need to disable register_globals in your php.ini.
Read more about register_globals here http://php.net/manual/en/security.globals.php
Related
Can someone give some examples of what register_globals are?
And is global $user_id; considered a register global?
The register_globals directive:
register_globals is an internal PHP setting which registers the $_REQUEST array's elements as variables. If you submit a value in a form, via POST or GET, the value of that input will automatically be accessible via variable in the PHP script, named after the name of the input field.
In other words, if you submitted a form containing a username text field, the expression ($username === $_POST['username']) at the very beginning of the script would return true.
Its notoriety is attributed to the fact that it opens lots of security holes, especially for people that follow anything less than a strict coding style from a security perspective.
Classic example:
if(user_is_admin($user))
{
$authorized = true;
}
if($authorized)
{
// let them do anything they want
}
Now, if you visited that script in a web browser and the server had register_globals on, you could simply append ?authorized=1 to the URL and god-mode would be enabled!
The global keyword:
global is a keyword has little to do with register_globals.
Here is an example of its use:
$foo = 'bar';
baz();
function baz()
{
echo $foo; // PHP warns you about trying to use an uninitialized variable
// and nothing is output (because $foo doesn't exist here)
}
buzz();
function buzz()
{
global $foo; // Enables the use of $foo in this scope
echo $foo; // Prints 'bar' to screen
}
Everyone mentioning GET, POST, REQUEST, COOKIE has effect on register_globals=on.
I'm just writing this to let you know that -
$_SESSION will be affected aswell because of register_globals=on.
http://php.net/manual/en/security.globals.php
That means - if you do as following -
$_SESSION[x] = 123;
$x = 'asd';
echo $_SESSION[x];
The output will be asd.
And this will cause serious security issues and bugs. I have experienced such a bad thing recently during using Hostgator shared hosting. By Default they have register_globals=on.
When you have register_globals=on, anything passed via GET or POST or COOKIE automatically appears to be global variable in code, this might have security consequences.
I.e. you click on url test.php?access_level=100 and you'll have $access_level = 100 in PHP.
When you do global $somevar - you are making your own global variable, which usually is not a big issue.
The register_globals setting controls how you access form, server, and environment. variables.
register_globals=On :
You can access form attribute without Global Arrays ( GET[], POST[] & REQUEST[] )
example: http://www.example.com/one.php?myinput=abc
You can access directly in one.php
echo $myinput; // abc
register_globals=Off :
You have to access all attributes only by Global Arrays.
example: http://www.example.com/one.php?myinput=abc
You have to access in one.php
echo $_GET['myinput']; //abc
As I understand it, if you have register globals turned ON, then anything passed in a GET or POST gets automatically translated into a variable in PHP.
for example:
http://www.domain.com/vars.php?myvar=123
without any further coding this would automatically get turned into a variable available to the rest of your php code
$myvar //with a value of 123
With registered globals OFF, data passed in via GET or POST is NOT automatically translated into a variable, rather, you need to request it using the Superglobals $_GET, $_POST, and $_REQUEST, etc.
http://php.net/manual/en/security.globals.php provides some further information as to the security implications of this.
Others can feel free to correct me if I'm wrong.
edit:
in relation to your question re global $user_id;, this does not create a 'global' in the sense of 'register_globals'. It simply alters the scope of a variable within the PHP code.
For information re scope, see: http://php.net/manual/en/language.variables.scope.php
Global variables in php are variables that are always accessible. They are also known as superglobals. They are built in variables that are always available regardless of the scope.
There are nine superglobal variables in PHP. Some of these are relevant to this discussion.
$_REQUEST
$_POST
$_GET
$_COOKIE
Now, let's focus on the $_REQUEST superglobal. It is used to collect data after submitting an HTML form by user using the POST method.
$_POST and $_REQUEST could be used loosely interchangeably. But $_REQUEST also contains $_GET and $_COOKIE along with $_POST so you are never sure if your data came from a web form.
Now, as pointed out by #Tim register_globals is an internal PHP setting which registers the $_REQUEST array's elements as variables. It is also known as a flag in your php setting. It is typically set in the PHP configuration file known as php.ini file. This setting can have two values.
“on”
“off”.
An “on” value means that PHP will automatically create global variables for many server variables as well as query string parameters. This is not good and is a security risk.
Register Globals :
register_globals
The feature causes data passed to a PHP script via cookies or GET and POST requests to be made available as global variables in the script.
Default Value : "0"
Changeable : PHP_INI_PERDIR
register_globals is affected by the variables_order directive.
NOTE:
This feature has been DEPRECATED as of PHP 5.3.0 and REMOVED as of PHP 5.4.0.
register_globals is one of the parameters of php.ini file.The file was coming from "On" mode before PHP 5.3.8 version.If you change register_globals from Off to On, there would be some criticals about vulnerability of website.Register_globals's feature is that you can use variables without $_GET and $_POST variables.So, Any data which comes from form or URL line you can use the variable not need like $_GET or $_POST variables.Example we have this form :
<?php
if(isset($_POST["myinput"])){
echo $_POST["username"];
}?>
<form action="" method="post">
<input type="text" name="username">
<input type="hidden" name="myinput">
<input type="submit" value="Submit">
</form>
When you submitted the form you can see your username but when you change the situation of register_globals to "On" you have not written $_POST["username"]; you can access directly to the username variable by writing this code echo $username
I am having problems with my $_SESSION values becoming unset. It all started when my host said that I had to put a PHP.INI file in the root directory of my application. I created the following PHP.ini file and put it in the root directory (/public_html) of my web server:
PHP.INI
magic_quotes_gpc = Off
magic_quotes_runtime = Off
magic_quotes_sybase = Off
display_errors = off
display_startup_errors = off
When I don't have this PHP.INI, my website works fine. When users log in, my session variables stay persistent until I kill them off using my logout function. I set a variable $_SESSION['user_id'] to determine whether someone is logged in.
But with the PHP.INI in place in my public_html directory, my sessions start falling apart.**
The peculiar thing is that it only happens when I do an AJAX call. I am using jQuery to make the ajax calls and POSTING a value to it.
I have tried many different things to try to get it to work with the PHP.INI in place, but sadly it all leads to me just having to allow error reporting and magic quotes... both of which should be disabled in a production environment!!
I'm almost certain it's not my code... how could turning errors off or magic quotes off cause my $_SESSION values to become empty?
I only set my $_SESSION['user_id'] variable once in my code and I have tried stripping out all mentions of unsetting $_SESSION, setting it to array() or destroying my session.
The session stays intact, in that the session_id() remains the same and I have a piece of code that confirms that the value was set.
I am starting all of my pages, including the ones called via AJAX in the same way, like so:
<?php
//
// This file returns data for quiz activity on yourquiz.php
//
define ('FILE_MAKE_QUIZ_ACCEPT', true);
$file_path = "../../";
$link_path = "./";
require_once ($file_path . 'func/base_classes.php');
require_once ($file_path . 'func.php');
// Must be logged in to return data back
Session::MustBeLoggedIn(false);
It is only when I remove the reference to func.php that it will load without UNSETTING all of the $_SESSION variables.
Here is my func.php code:
<?php
// Specify the session name
session_name('maq');
session_start();
if (! defined ( 'FILE_MAKE_QUIZ_ACCEPT' )) {
echo "Possible hacking Attempt";
exit ();
}
// Define constants
/**
* The base URL of uQuiz for a trailing slash
* #var constant
*/
define("##########", '##########');
// Get the database connection
$db_con = Db::GetConnection();
// Run Session Update Function if they are logged in still
// This runs once every page load
Session::UpdateSession();
I have tried commenting out the GetConnection and UpdateSession from func.php, but it still unsets my $_SESSION variables.
It's completely bizarre. Any ideas what could cause this?
My sugestions
1)
First I would reactivate
display_errors = on
display_startup_errors = on
debugging with errors off is almost impossible. And then check if any error is reported.
2)
I've seen similar behavior in some hosts, where PHP.INI simply replaces the "system's" php.ini instead of merging. This means php goes to default configuration + your php.ini.
The best way to check this is running php_info() both with and without your php.ini in the root directory and spot the differences. If more than magic quotes and error reporting is changed, then
that's probably the problem.
In that case try disabling magic quotes in htaccess, something like this:
php_flag magic_quotes_gpc Off
3)
If that's not the case, then there must be a problem in your sql queries. Maybe you forgot to escape a character and php magic quotes was doing it for you.
I got a piece of code:
$_SESSION['cms_lang'] = 2;
global $cms_lang;
$cms_lang[1] = 'en';
Error:
Cannot use a scalar value as an array
Problem is that, I really don't know why server sees my global variable as the same as $_SESSION variable. I used this piece of code a couple of times and never had problem with that. I guess it must depends of settings on server. Can anyone know how to force server to not take global and session variables with the same name as the same?
You may read up on the PHP configuration setting register_globals which enables this behavior.
Also, read about why you should disable it (and generally, upgrade your PHP version!)
Can someone give some examples of what register_globals are?
And is global $user_id; considered a register global?
The register_globals directive:
register_globals is an internal PHP setting which registers the $_REQUEST array's elements as variables. If you submit a value in a form, via POST or GET, the value of that input will automatically be accessible via variable in the PHP script, named after the name of the input field.
In other words, if you submitted a form containing a username text field, the expression ($username === $_POST['username']) at the very beginning of the script would return true.
Its notoriety is attributed to the fact that it opens lots of security holes, especially for people that follow anything less than a strict coding style from a security perspective.
Classic example:
if(user_is_admin($user))
{
$authorized = true;
}
if($authorized)
{
// let them do anything they want
}
Now, if you visited that script in a web browser and the server had register_globals on, you could simply append ?authorized=1 to the URL and god-mode would be enabled!
The global keyword:
global is a keyword has little to do with register_globals.
Here is an example of its use:
$foo = 'bar';
baz();
function baz()
{
echo $foo; // PHP warns you about trying to use an uninitialized variable
// and nothing is output (because $foo doesn't exist here)
}
buzz();
function buzz()
{
global $foo; // Enables the use of $foo in this scope
echo $foo; // Prints 'bar' to screen
}
Everyone mentioning GET, POST, REQUEST, COOKIE has effect on register_globals=on.
I'm just writing this to let you know that -
$_SESSION will be affected aswell because of register_globals=on.
http://php.net/manual/en/security.globals.php
That means - if you do as following -
$_SESSION[x] = 123;
$x = 'asd';
echo $_SESSION[x];
The output will be asd.
And this will cause serious security issues and bugs. I have experienced such a bad thing recently during using Hostgator shared hosting. By Default they have register_globals=on.
When you have register_globals=on, anything passed via GET or POST or COOKIE automatically appears to be global variable in code, this might have security consequences.
I.e. you click on url test.php?access_level=100 and you'll have $access_level = 100 in PHP.
When you do global $somevar - you are making your own global variable, which usually is not a big issue.
The register_globals setting controls how you access form, server, and environment. variables.
register_globals=On :
You can access form attribute without Global Arrays ( GET[], POST[] & REQUEST[] )
example: http://www.example.com/one.php?myinput=abc
You can access directly in one.php
echo $myinput; // abc
register_globals=Off :
You have to access all attributes only by Global Arrays.
example: http://www.example.com/one.php?myinput=abc
You have to access in one.php
echo $_GET['myinput']; //abc
As I understand it, if you have register globals turned ON, then anything passed in a GET or POST gets automatically translated into a variable in PHP.
for example:
http://www.domain.com/vars.php?myvar=123
without any further coding this would automatically get turned into a variable available to the rest of your php code
$myvar //with a value of 123
With registered globals OFF, data passed in via GET or POST is NOT automatically translated into a variable, rather, you need to request it using the Superglobals $_GET, $_POST, and $_REQUEST, etc.
http://php.net/manual/en/security.globals.php provides some further information as to the security implications of this.
Others can feel free to correct me if I'm wrong.
edit:
in relation to your question re global $user_id;, this does not create a 'global' in the sense of 'register_globals'. It simply alters the scope of a variable within the PHP code.
For information re scope, see: http://php.net/manual/en/language.variables.scope.php
Global variables in php are variables that are always accessible. They are also known as superglobals. They are built in variables that are always available regardless of the scope.
There are nine superglobal variables in PHP. Some of these are relevant to this discussion.
$_REQUEST
$_POST
$_GET
$_COOKIE
Now, let's focus on the $_REQUEST superglobal. It is used to collect data after submitting an HTML form by user using the POST method.
$_POST and $_REQUEST could be used loosely interchangeably. But $_REQUEST also contains $_GET and $_COOKIE along with $_POST so you are never sure if your data came from a web form.
Now, as pointed out by #Tim register_globals is an internal PHP setting which registers the $_REQUEST array's elements as variables. It is also known as a flag in your php setting. It is typically set in the PHP configuration file known as php.ini file. This setting can have two values.
“on”
“off”.
An “on” value means that PHP will automatically create global variables for many server variables as well as query string parameters. This is not good and is a security risk.
Register Globals :
register_globals
The feature causes data passed to a PHP script via cookies or GET and POST requests to be made available as global variables in the script.
Default Value : "0"
Changeable : PHP_INI_PERDIR
register_globals is affected by the variables_order directive.
NOTE:
This feature has been DEPRECATED as of PHP 5.3.0 and REMOVED as of PHP 5.4.0.
register_globals is one of the parameters of php.ini file.The file was coming from "On" mode before PHP 5.3.8 version.If you change register_globals from Off to On, there would be some criticals about vulnerability of website.Register_globals's feature is that you can use variables without $_GET and $_POST variables.So, Any data which comes from form or URL line you can use the variable not need like $_GET or $_POST variables.Example we have this form :
<?php
if(isset($_POST["myinput"])){
echo $_POST["username"];
}?>
<form action="" method="post">
<input type="text" name="username">
<input type="hidden" name="myinput">
<input type="submit" value="Submit">
</form>
When you submitted the form you can see your username but when you change the situation of register_globals to "On" you have not written $_POST["username"]; you can access directly to the username variable by writing this code echo $username
I have one of those "I swear I didn't touch the server" situations. I honestly didn't touch any of the php scripts. The problem I am having is that php data is not being saved across different pages or page refreshes. I know a new session is being created correctly because I can set a session variable (e.g. $_SESSION['foo'] = "foo" and print it back out on the same page just fine. But when I try to use that same variable on another page it is not set! Is there any php functions or information I can use on my hosts server to see what is going on?
Here is an example script that does not work on my hosts' server as of right now:
<?php
session_start();
if(isset($_SESSION['views']))
$_SESSION['views'] = $_SESSION['views']+ 1;
else
$_SESSION['views'] = 1;
echo "views = ". $_SESSION['views'];
echo '<p>Refresh</p>';
?>
The 'views' variable never gets incremented after doing a page refresh. I'm thinking this is a problem on their side, but I wanted to make sure I'm not a complete idiot first.
Here is the phpinfo() for my hosts' server (PHP Version 4.4.7):
Thanks for all the helpful info. It turns out that my host changed servers and started using a different session save path other than /var/php_sessions which didn't exist anymore. A solution would have been to declare ini_set(' session.save_path','SOME WRITABLE PATH'); in all my script files but that would have been a pain. I talked with the host and they explicitly set the session path to a real path that did exist. Hope this helps anyone having session path troubles.
Check to make sure you are not mixing https:// with http://. Session variables do not flow between secure and insecure sessions.
Had same problem - what happened to me is our server admin changed the session.cookie_secure boolean to On, which means that cookies will only be sent over a secure connection. Since the cookie was not being found, php was creating a new session every time, thus session variables were not being seen.
Use phpinfo() and check the session.* settings.
Maybe the information is stored in cookies and your browser does not accept cookies, something like that.
Check that first and come back with the results.
You can also do a print_r($_SESSION); to have a dump of this variable and see the content....
Regarding your phpinfo(), is the session.save_path a valid one? Does your web server have write access to this directory?
Hope this helps.
I had following problem
index.php
<?
session_start();
$_SESSION['a'] = 123;
header('location:index2.php');
?>
index2.php
<?
session_start();
echo $_SESSION['a'];
?>
The variable $_SESSION['a'] was not set correctly. Then I have changed the index.php acordingly
<?
session_start();
$_SESSION['a'] = 123;
session_write_close();
header('location:index2.php');
?>
I dont know what this internally means, I just explain it to myself that the session variable change was not quick enough :)
Check to see if the session save path is writable by the web server.
Make sure you have cookies turned on.. (I forget when I turn them off to test something)
Use firefox with the firebug extension to see if the cookie is being set and transmitted back.
And on a unrelated note, start looking at php5, because php 4.4.9 is the last of the php4 series.
Check who the group and owner are of the folder where the script runs. If the group id or user id are wrong, for example, set to root, it will cause sessions to not be saved properly.
Check the value of "views" when before you increment it. If, for some bizarre reason, it's getting set to a string, then when you add 1 to it, it'll always return 1.
if (isset($_SESSION['views'])) {
if (!is_numeric($_SESSION['views'])) {
echo "CRAP!";
}
++$_SESSION['views'];
} else {
$_SESSION['views'] = 1;
}
Well, we can eliminate code error because I tested the code on my own server (PHP 5).
Here's what to check for:
Are you calling session_unset() or session_destroy() anywhere? These functions will delete the session data immediately. If I put these at the end of my script, it begins behaving exactly like you describe.
Does it act the same in all browsers? If it works on one browser and not another, you may have a configuration problem on the nonfunctioning browser (i.e. you turned off cookies and forgot to turn them on, or are blocking cookies by mistake).
Is the session folder writable? You can't test this with is_writable(), so you'll need to go to the folder (from phpinfo() it looks like /var/php_sessions) and make sure sessions are actually getting created.
If you set a session in php5, then try to read it on a php4 page, it might not look in the correct place! Make the pages the same php version or set the session_path.
I spent ages looking for the answer for a similar problem. It wasn't an issue with the code or the setup, as a very similar code worked perfectly in another .php on the same server. Turned out the problem was caused by a very large amount of data being saved into the session in this page. In one place we had a line like this:$_SESSION['full_list'] = $full_list where $full_list was an array of data loaded from the database; each row was an array of about 150 elements. When the code was initially written a couple of years ago, the DB only contained about 1000 rows, so the $full_list contained about 100 elements, each being an array of about 20 elements. With time, the 20 elements turned into 150 and 1000 rows turned into 17000, so the code was storing close to 64 meg of data into the session. Apparently, with this amount of data being stored, it refused to store anything else. Once we changed the code to deal with data locally without saving it into the session, everything worked perfectly.
I know one solution I found (OSX with Apache 1 and just switched to PHP5) when I had a similar problem was that unsetting 1 specific key (ie unset($_SESSION['key']);) was causing it not to save. As soon as I didn't unset that key any more it saved. I have never seen this again, except on that server on another site, but then it was a different variable. Neither were anything special.
Thanks for this one Darryl. This helped me out. I was deleting a session variable, and for some reason it was keeping the session from committing. now i'm just setting it to null instead (which is fine for my app), and it works.
I know one solution I found (OSX with Apache 1 and just switched to PHP5) when I had a similar problem was that unsetting 1 specific key (ie unset($_SESSION['key']);) was causing it not to save. As soon as I didn't unset that key any more it saved. I have never seen this again, except on that server on another site, but then it was a different variable. Neither were anything special.
Here is one common problem I haven't seen addressed in the other comments: is your host running a cache of some sort? If they are automatically caching results in some fashion you would get this sort of behavior.
Just wanted to add a little note that this can also occur if you accidentally miss the session_start() statement on your pages.
Check if you are using session_write_close(); anywhere, I was using this right after another session and then trying to write to the session again and it wasn't working.. so just comment that sh*t out
I had session cookie path set to "//" instead of "/". Firebug is awesome.
Hope it helps somebody.
I had this problem when using secure pages where I was coming from www.domain.com/auth.php that redirected to domain.com/destpage.php. I removed the www from the auth.php link and it worked. This threw me because everything worked otherwise; the session was not set when I arrived at the destination though.
A common issue often overlooked is also that there must be NO other code or extra spacing before the session_start() command.
I've had this issue before where I had a blank line before session_start() which caused it not to work properly.
Adding my solution:
Check if you access the correct domain. I was using www.mysite.com to start the session, and tried to receive it from mysite.com (without the www).
I have solved this by adding a htaccess rewrite of all domains to www to be on the safe side/site.
Also check if you use http or https.
Edit your php.ini.
I think the value of session.gc_probability is 1, so set it to 0.
session.gc_probability=0
Another few things I had to do (I had same problem: no sesson retention after PHP upgrade to 5.4). You many not need these, depending on what your server's php.ini contains (check phpinfio());
session.use_trans_sid=0 ; Do not add session id to URI (osc does this)
session.use_cookies=0; ; ensure cookies are not used
session.use_only_cookies=0 ; ensure sessions are OK to use IMPORTANT
session.save_path=~/tmp/osc; ; Set to same as admin setting
session.auto_start = off; Tell PHP not to start sessions, osc code will do this
Basically, your php.ini should be set to no cookies, and session parameters must be consistent with what osc wants.
You may also need to change a few session code snippets in application_top.php - creating objects where none exist in the tep_session_is_registered(...) calls (e eg. navigation object), set $HTTP_ variables to the newer $_SERVER ones and a few other isset tests for empty objects (google for info). I ended up being able to use the original sessions.php files (includes/classes and includes/functions) with a slightly modified application_top.php to get things going again. The php.ini settings were the main problem, but this of course depends on what your server company has installed as the defaults.