Page 1 of 1

Session Variables and multiple tabs

Posted: Mon Jan 18, 2010 8:20 am
by Cerddaf
We've got several incarnations at various clients of a bespoke ecommerce site using Session Variables to hold the cart details and other details.

We've become aware of a problem when the user clones their web browser window either into a new tab or a complete new process.
Although there are now 2 (or more) web pages displaying on their PC, there is still only 1 session shared between them.

So if the user uses webpage A to order stuff, then suddenly switches to the other window for some reason, then switches back (and yes some people have done that), then to the PHP script processing the submitted data there can appear to be corruption in the session variables.
In fact it's not corruption, it's the result of a change on the other window, which is perfectly valid in itself, but appears like corruption to the other webpage.

Does anyone have a recommended way of dealing with this?
- Hold all cart info etc in hidden fields on the web page?
- hold session variables as arrays, a row per webpage. Then try to spot when a new window is created, and assign a new row in the session array variable?

Cheers - Malcolm

Re: Session Variables and multiple tabs

Posted: Mon Jan 18, 2010 3:08 pm
by tr0gd0rr
What do you mean exactly by "corruption in the session variables"?

I can give some general thoughts. Web apps are stateless and this is a common problem. There is no way to detect if a user opens a new window or tab. Here are a few suggestions:

1. Recheck the user's status before performing an action. For example, check $_SESSION to see if the user already submitted their order and don't charge their credit card twice.
2. Track the user's current action. For example, if the user is on step 3 of a 5-step checkout process, allow subsequent requests to only go to step 2, 3 or 4.
3. Allow users to only have one session open at a time (e.g. prevent them from logging in twice).

As far as sessions versus hidden inputs, avoid hidden inputs--they can open you up to hacking pretty easily. I like to store a lot of details in session instead of requerying the database each request. The rule I personally follow is to only store data that applies to that one user and to keep the session data below about 50kb for each session.

It can be a complex problem. I worked through an issue a while back where users could add money to their account by redeeming gift certificates. One guy used cash to buy a $500 gift certificate. He then made a script to hit the server something like 10,000 times within one second. In the short time between checking if the certificate had already been redeemed and marking it as redeemed, 6 of the 10,000 requests made it through. The app added $3000 to his account! One of the parts of the fix was to use a SQL transaction.

So if you are facing hacking situations, you have to be even more careful in the stateless environment.

Re: Session Variables and multiple tabs

Posted: Tue Jan 19, 2010 10:48 pm
by PHPHorizons
tr0gd0rr wrote:What do you mean exactly by "corruption in the session variables"?
I'd second that. My guess is the session data is not corrupt since it's stored on the server side. It's the user interface that appears to show corrupt session data. If I have that wrong, then what I say next may not apply.

I am assuming that you are using ajax, or frames, or iframes. Otherwise, the entire page should be refreshed and this "synchronization" problem would not be a problem. When the client sends an ajax request, a key could be sent. This key would be linked to the last ajax request response. In response to the new request, generate a new key and send it out. That new key would be sent back back on the next request.

If a user switches up browser windows/tabs on you, you would instantly know if the key sent was the last and newest key. If it was, then you can assume all is fine. If it wasn't, then you should signal the browser to reload the page, or you can manually refresh all the data that needs to be refreshed.

Hope that helps.