A look into sessions and security

Part #2: Storage, Access and Meta Data

Er Galvao Abbott
The White Hat ElePHPant
4 min readJun 12, 2017

--

In my second article we’ve seen how to set up a session in a way that improves it’s security. We’ll now take a look at a few issues about access, storage and meta data.

Storage and Access:

In our “final” product we’ll have the session stored in three different ways: the session itself (in PHP the $_SESSION superglobal array), a database entity and an object.

While this might seem like overdoing it, we have good reasons to follow this:

  1. We centralize access to the session through the object;
  2. We can store the data benefiting from the database type system and constraints, aside from being able to store data that doesn’t need to reside in the session itself;
  3. We may use some programming logic for specific needs (more on this below).

Point #1 might be represented as such:

Fig. 1: The Session object acts as the single access point between the database entity and the session itself

And the session entity on the database could be something like this:

A proposed database entity for our session

Meta Data — or more specifically session validity

The central point in this article is about whether a session is considered valid or not. Most (if not all) of the following points are best enforced through programming logic, which justifies the use of an object to control the session. Aside from that, the main concept of a valid session can be boiled down to a single word: coherence.

A sesssion must be destroyed — and therefore the user must be logged out of the application — when:

  • The session is “inactive” (It’s lifetime has expired. Once again, I’ll talk a bit more about “eternal sessions” soon);
  • The user is promoted/demoted[1].

A session is considered invalid — and therefore must be locked — when:

  • There’s an attempt to create a new session for a user who’s already logged in[2] — which is enforced through the use of a Primary Foreign Key from the account entity;
  • The user’s IP Address changes during a single acess[3, also see the role example below];
  • There’s an attempt to change the account ID (the user) related to it (once again see the example of the role setter). Aside from (not less important) privacy issues, this would be a case against what’s commonly called as “privilege escalation”, the attempt to gain a role which wasn’t intended for the user. This is a bit obvious, but when talking about security something being obvious is never an excuse to overlook it;
  • If it’s access token is not informed by the application or doesn’t match the one previously set. The access token in this case may be used for a variety of scenarios, but it’s best known as a security measure against CSRF attacks.
  • The role of the user changes without being edited by an administrator. This particular point also prevents privilege escalation and remains one of the best examples for implementing the getters and setters pattern: the role of the user can only be set once, and therefore should only be set if it’s value is — in case of PHP — NULL. Here is a simple example:

Points that need clarification:

[1] — In case of promoting/demoting users (which would obviously cause a legitimate change in the user’s role) the user’s session must be destroyed and the user needs to re-authenticate with the application. While this may cause usability and even very complex logic issues — let’s say a user is typing in a form and is promoted/demoted before sending the data — the process of logging him/her out is still paramount.

[2] — While this shouldn’t have to be said, simulated access (“seeing the application through the eyes of a particular user”) is a way more complicated subject which involves a lot of different concepts — including, but not limited to, data privacy — and it’s beyond the scope of this series. Nevertheless this process is not equal to using the same session of the user or even creating a new session for the same user (which, once again, should be pretty obvious, but anyway…).

[3] —IP Addresses changes aren’t inherently a security violation. In the past (and may or may not be still the case in specific countries/ISPs/etc…) IP addresses would change all the time. Nowadays this is best exemplified by multiple devices connecting to the same application (which also serves as a possible justification for having multiple sessions for the same user). In these particular scenarios there is a couple of different (and way more complicated) approaches that might be needed, which I’ll briefly discuss in the next article.

Why locking — instead of just destroying — an invalid session

As it might transpire through this article alone (not to mention the series itself), security is a very complicated subject and as such cannot be dealt with simple automated processes.

Locking a session (if not clear enough, preventing a user from authenticating itself again) have a few benefits to everyone involved:

  • For the user who owns the account, it prevents further damage. This also ends up benefiting the project owner, since it keeps damage to a minimum;
  • For the tech team, it provides an aopportunity to study the application and search for the vulnerability exploited in order to violate the validity of the session (provided there are extensive logging and other debugging/analytical assets, but that’s another story).

Next…

On my next article I’ll briefly talk about how we can make a more complex implementation that should prevent false alarms while still providing a decent level of security. See you then!

--

--

Er Galvao Abbott
The White Hat ElePHPant

Brazilian programmer and web app security advisor; Zend Framework Evangelist.