phpsecuritysession-variablesbest-fit

Is $_SESSION a proper way to transport data across many pages securely?


The application I'm making requires users to get different content upon login based on their user type and permissions. The information retrieved from them at login will be needed across several pages.

My idea was to make a class called 'users', create an instance at login, set all its attributes using the database, then set a $_SESSION as this object so it can be accessed across the website to create the desired display.

Is this a proper and secure practice?


Solution

  • As always, implementation details matter the most. In general, using the session for persisting state related to a user logon session is fine, actually, that is the purpose of sessions. However, there are caveats.

    Objects and serialization

    Anytime you store an object in the session, it will be serialized, and anytime you read it back, it will be deserialized. This works for simple value objects, but may not work if your class includes things like a file or database link reference. In the worst case and under special circumstances, this may even lead to security issues, but that is actually unlikely to happen. But serialization itself may easily fail on some objects.

    Session stores

    You have several options for your session store. It can be your application/web server memory, your server may persist session contents to files, or store them in a SQL or NoSQL database, etc. Access control to the session store is key, anyone having access to the session store can modify session contents for any user. For example Redis is often used for storing session data, but Redis access control is not very strong. Also if session data is stored on the web server, any admin on the server will have pratically unlimited access to any logged on user's session, which may or may not be a problem, depending on your scenario.

    The cache invalidation problem

    If you only query the database once and store data in the session after the first query, you are essentially using the session as a cache, with all related problems. The most important of these from a security perspective is probably cache invalidation. Imagine you're storing user access rights to the session upon logon so you don't have to query them anymore. What if the user logs on and keeps alive his session for a long time (as long as your absolute session timeout allows, if there is any), but his access rights change meanwhile, most importantly, if rights are revoked? Your cache in the session will be invalid, unless you design logic to invalidate the cache, which may be quite difficult with some session stores, and still complex with the easier ones. One way to mitigate this risk is to implement forced logout, but that also has implications on the session store you use.

    Session-related application vulnerabilities

    Another threat that comes to mind is that due to security flaws in your source code, your application may allow a user to edit session contents to some extent. If you store the whole object in the session and never again consult the database, such a vulnerability may allow an attacker to elevate his privileges and gain access to things he was not supposed to have access to. Obviously, the likelihood of such a vulnerability that would allow editing session contents is probably not very high, and if there is such a vulnerability, that would also affect your application if it turned to the database on every request. However, the impact of such an attack could probably be lower in the latter case.

    Conclusion

    It is not inherently insecure to store your user objects in the session. You can do that if you mitigate or accept the risks. However, you should know about the issues detailed above and decide for yourself whether they are genuine risks for your application and whether you can mitigate or want to accept them.