tags:

views:

2077

answers:

16

One thing I've started doing more often recently is retrieving some data at the beginning of a task and storing it in a $_SESSION['myDataForTheTask'].

Now it seems very convenient to do so but I don't know anything about performance, security risks or similar, using this approach. Is it something which is regularly done by programmers with more expertise or is it more of an amateur thing to do?

For example:

if (!isset($_SESSION['dataentry']))
{
    $query_taskinfo = "SELECT participationcode, modulearray, wavenum FROM mng_wave WHERE wave_id=".$_GET['wave_id'];
    $result_taskinfo = $db->query($query_taskinfo);
    $row_taskinfo = $result_taskinfo->fetch_row();

        $dataentry = array("pcode" => $row_taskinfo[0], "modules" => $row_taskinfo[1], "data_id" => 0, "wavenum" => $row_taskinfo[2], "prequest" => FALSE, "highlight" => array());

        $_SESSION['dataentry'] = $dataentry;
}

I'm an amateur so feel free to comment other aspects of that code.

+1  A: 

$_SESSION items are stored in the session, which is, by default, kept on disk. There is no need to make your own array and stuff it in a 'dataentry' array entry like you did. You can just use $_SESSION['pcode'], $_SESSION['modules'] and so on.

Like I said, the session is stored on disk and a pointer to the session is stored in a cookie. The user thus can't easily get ahold of the session data.

nsayer
But what if I want to loop through all my vars for this task say with foreach, then it's better to have it in $_SESSION['mystuff'] otherwise I would half to loop through the whole session and get all the other stuff which is there too. No?
tharkun
Just use a multidimensional array$_SESSION['mystuff']['mydata'] = 'blah';
conmulligan
@conmulligan: Sure, but nothing is going to be in the session except what you put there. You may be confusing $_SESSION with $_SERVER.
nsayer
A: 

I use this approach a fair bit, I don't see any problem with it. Unlike cookies, the data isn't stored at the client-side, which is often a big mistake.

Like anything though, just be careful that you're always sanitising user input, especially if you're putting user input into the $_SESSION variable, then later using that variable in an SQL query.

Steve M
+3  A: 

There are a few factors you'll want to consider when deciding where to store temporary data. Session storage is great for data that is specific to a single user. If you find the default file-based session storage handler is inefficient you can implement something else, possibly using a database or memcache type of backend. See session_set_save_handler for more info.

I find it is a bad practice to store common data in a user's session. There are better places to store data that will be frequently accessed by several users and by storing this data in the session you will be duplicating the data for each user who needs this data. In your example, you might set up a different type of storage engine for this wave data (based on wave_id) that is NOT tied specifically to a user's session. That way you'll pull the data down once and them store it somewhere that several users can access the data without requiring another pull.

pix0r
+1  A: 

IMO, it's perfectly acceptable to store things in the session. It's a great way to make data persistent. It's also, in many cases, more secure than storing everything in cookies. Here are a few concerns:

  • It's possible for someone to hijack a session, so if you're going to use it to keep track of user authorization, be careful. Read this for more information.
  • It can be a very lazy way to keep data. Don't just throw everything in the session so that you don't have to query for it later.
  • If you're going to store objects in the session, either their class files will need to be included before the session is started on the next request or you'll need to have configured an auto loader.
Lucas Oman
+1  A: 

If you're running on your own server, or in an environment where nobody can snoop on your files/memory on the server, session data are secure. They're stored on the server and just an identification cookie sent to the client. The problem is if other people can snatch the cookie and impersonate someone else, of course. Using HTTPS and making sure to not put the session ID in URLs should keep your users safe from most of those problems. (XSS might still be used to snatch cookies if you aren't careful, see Jeef Atwoods post on this too.)

As for what to store in a session variable, put your data there if you want to refer to it again on another page, like a shopping basket, but don't put it there if it's just temporary data used for producing the result of this page, like a list of tags for the currently viewed post. Sessions are for per-user persistent data.

jfs
A: 

This is a fairly common thing to do, and the session is generally going to be faster than continuous database hits. They're also reasonably secure, as the PHP devs have worked hard to prevent Session Hijacking.

The only issue is that you need to remember to rebuild the session entry when something changes. And, if anything is changed by a user other than the one who owns the session that would result in a need to refresh this key, there is no easy way to notify the system to refresh this session key. Possibly not a big deal, but something you should be aware of.

foxxtrot
+2  A: 

I use the session variable all the time to store information for users. I haven't seen any issues with performance. The session data is pulled based on the cookie (or PHPSESSID if you have cookies turned off). I don't see it being any more of a security risk than any other cookie based authentication, and probably more secure than storing the actual data in the users cookie.

Just to let you know though, you do have a security issue with your SQL statement: "SELECT participationcode, modulearray, wavenum FROM mng_wave WHERE wave_id=".$_GET['wave_id'];

You should NEVER, I REPEAT NEVER, take user provided data and use it to run a SQL statement without first sanitizing it. I would wrap it in quotes and add the function "mysql_real_escape_string()". That will protect you from most attacks. So your line would look like:

$query_taskinfo = "SELECT participationcode, modulearray, wavenum FROM mng_wave WHERE wave_id='".mysql_real_escape_string($_GET['wave_id'])."'";
Ryan Smith
thanks! this stak overflow makes me learn in an incredible pace, I'm amazed.
tharkun
+1  A: 

Zend Framework has a useful library for session data management which helps with expiry and security (for stuff like captchas). They also have a useful explanation of sessions. See http://framework.zend.com/manual/en/zend.session.html

+7  A: 

Well Session variables are really one of the only ways (and probably the most efficient) of having these variables available for the entire time that visitor is on the website, there's no real way for a user to edit them (other than an exploit in your code, or in the PHP interpreter) so they are fairly secure.

It's a good way of storing settings that can be changed by the user, as you can read the settings from database once at the beginning of a session and it is available for that entire session, you only need to make further database calls if the settings are changed and of course, as you show in your code, it's trivial to find out whether the settings already exist or whether they need to be extracted from database.

I can't think of any other way of storing temporary variables securely (since ookies can easily be modified and this will be undesirable in most cases) so $_SESSION would be the way to go

HappySmileMan
"they are fairly secure" is only true if it is a dedicated server. on shared hosting other users on the same machine can access php-session data.
Jacco
Not if you choose to store your session data in some place other than the default. Or when you use a different session storage mechanism, like DB or (your own private) memcache.
Anti Veeranna
A: 

I just need to say that this is amazing :D I'm stunned at the quality, quantity and return speed of the answers... haha! GREAT! keep going guys!

tharkun
+2  A: 

Another way to improve the input validation is to cast the _GET['wave_id'] variable:

$query_taskinfo = "SELECT participationcode, modulearray, wavenum FROM mng_wave WHERE wave_id=".(int)$_GET['wave_id']." LIMIT 1";

I'm presuming wave_id is an integer, and that there is only one answer.

Will

William Macdonald
yes, exactly. thanks for the hint!
tharkun
+1  A: 

I have found sessions to be very useful, but a few things to note:

1) That PHP may store your sessions in a tmp folder or other directory that may be accessible to other users on your server. You can change the directory were sessions are stored by going to the php.ini file.

2) If you are setting up a high value system that needs very tight security you might want to encrypt the data before you send it to the session, and decrypt it to use it. Note: this might create too much overhead depending on your traffic / server capacity.

3) I have found that session_destroy(); doesn’t delete the session right away, you still have to wait for the PHP garbage collector to clean the sessions up. You can change the frequency that the garbage collector is run in the php.ini file. But is still doesn’t seem very reliable, more info http://www.captain.at/howto-php-sessions.php

+3  A: 

$_SESSION mechanism is using cookies.

In case of Firefox (and maybe new IE, I didn't check myself) that means that session is shared between opened tabs. That is not something you expect by default. And it means that session is no longer "something specific to a single window/user".

For example, if you have opened two tabs to access your site, than logged as a root using the first tab, you will gain root privileges in the other one.

That is really inconvenient, especially if you code e-mail client or something else (like e-shop). In this case you will have to manage sessions manually or introduce constantly regenerated key in URL or do something else.

+1  A: 

You might want to consider how REST-ful this is?

i.e. see "Communicate statelessly" paragraph in "A Brief Introduction to REST"...

"REST mandates that state be either turned into resource state, or kept on the client. In other words, a server should not have to retain some sort of communication state for any of the clients it communicates with beyond a single request."

(or any of the other links on wikipedia for REST)

So in your case, the 'wave_id' is a sensible Resource to GET, but do you really want to store it in the SESSION? Surely memcached is your solution to cacheing the object Resource?

Matt
+1  A: 

A few other disadvantages of using sessions:

  1. $_SESSION data will expire after *session.gc_maxlifetime* seconds of inactivity.
  2. You'll have to remember to call session_start() for every script that will use the session data.
  3. Scaling the website by load balancing over multiple servers could be a problem because the user will need to be directed to the same server each time. Solve this with "Sticky Sessions".
Tom
A: 

$_SESSION is very useful in security, since it is a server side way to store information while a user is actively on your pages, therefore hard to hack unless your actual php file or server has weaknesses that are exploited. One very good implementation is storing a variable to confirm that the user is logged in, and only allowing actions to be taken if they are confirmed logged in.

Bryan Grezeszak