Internet Security Hypersessions – Tracking multiple authentication states
It doesn’t happen often, but occasionally you will run into a problem where a feature cannot be handled with only one session. Imagine the situation where a user of your site needs access to a sub-system with completely independent security requirements; sometimes this can be handled by creating an authentication stack within a session. An example of this is SUID where a supervisor temporarily takes control of the session, but what do you do when both states are required at the same time? A good example of this is a payment gateway on your primary web site. A user on a secondary web site may need to make a payment through the primary web site gateway using account information from the secondary web site. Sure, you could logout the authenticated user on the primary web site in favor of the third party user from the second web site, but what if the user on the primary web site has a coupon that they’re trying to use that’s in their account on the primary web site? This isn’t the only situation where hypersessions can help, there are many. A voting system would be a good example where you need to ensure that people can only vote once even if they have accounts on multiple web sites under your control. This situation appears to be a paradox, and in some ways it is, but you can indeed solve this problem with multiple concurrent sessions.
The first thing to know about multiple sessions is that while they exist at the same time, it would be a mistake to mix authorization between the sessions. An example of this is that an administrator of the second site shouldn’t gain administrative privileges on the first site. In an object oriented language, you may be used to the pattern of checking $user->isadmin() and may be tempted to re-use $user for each of the sessions but this would make it easy for users from one site to gain privileges that they were never authorized to have. There are a few different ways of dealing with this situation, but I find it is easiest to reserve the user object for the local session, and use alternative user objects for secondary sessions, such as getSession($domain)->user->isadmin(). An equivalent in a functional language may be is_admin(get_user(get_session($domain))).
The second important issue is how to technically handle multiple sessions. Most platforms and frameworks don’t explicitly provide the ability to have more than one session active at a time. In this common situation you need to build your own session management system. A session is typically data which has been serialized and is stored under the session_id key. Building your own sessions requires generating your own session_id, serializing and unserializing the session data, and storing and retrieving the encoded session data. Once these systems are in place, you need to maintain session cookies which identify the session id. While you can follow normal usage of cookies and use a domain identifier as your cookie name (cookies[domain] = session_id), I find it more secure to use the cookie value to identify the domain (cookies[session_id] = domain) and loop through the cookies to identify the domain. As long as your session_id is sufficiently random, there is little chance of a collision with other cookies when doing it this way. This will make it slightly more difficult to identify and therefore manipulate session cookies. If your domain key is also encrypted, and you drop a few fake session cookies ,I dare say it may be impossible for a potential attacker to identify the session cookie. This, by no means, provides perfect security but it doesn’t hurt.
When I was first faced with the problem of multiple sessions, I wasn’t able to solve the problem. I did a lot of googling for a solution and read every bit of documentation I could find on session management and I couldn’t find any solution. It was only recently that I realized that to create a second session, you simply need to work outside of the established session systems. I hope by publishing this solution I can help you avoid rubber stamping these type of situations as impossible. It is easy to look at the available features of a system and deem something as impossible, but it is equally easy to add new features to a system to make the impossible a reality.