Tips for secure session management

In this article..
Use built-in session frameworks
Store session data on the server
Be aware of the data that is stored in session objects
Use short session timeout intervals
Use a session-id with sufficient entropy and length
Invalidate session on the server
Regenerate session-id when privilege changes
Set the secure and HTTPOnly flags on cookies
Do not use/reuse session-ids for any other purpose
Use valid SSL certificates
Regenerate Session-Ids when switching between HTTP and HTTPS

The biggest threat to web application sessions is session hijacking. There are many different ways to hijack sessions such as session fixation, interception (using XSS or similar attack), or prediction (sequencing, brute forcing).

Which ever way a session is compromised, it can result in sensitive information being stolen or unauthorized operations being performed. These can result in loss of brand image, compliance issues, etc and impact the organization’s finances. It is imperative to ensure that application sessions are secure. To that end, some tips are presented below:

1. Use built-in session frameworks
Almost every application framework comes with a built-in session management scheme. They generate session-ids and manage them. These mechanisms have been tested by the security community, vulnerabilities have been reported and fixed in most cases. Using these is way better than using a home-grown session management scheme, which may have unexposed vulnerabilities.

2. Store session data on the server
Every programming platform (ASP, .Net, J2EE, PHP, etc) provide a way to store session data in session objects. These objects are stored on the server and prevent direct end user access. Using session objects can cause issues when using multiple servers behind a load-balancer, but there are workarounds such as using a DB or file system as a common repository. In any case, storing session data in end-user accessible elements such as hidden fields should be avoided.

3. Be aware of the data that is stored in session objects
Programmers need to be aware of what data is stored in session objects. Depending on where the session objects are stored (DB, file-system, RAM, etc) and what data is stored, different regulations may be applicable. For instance, if session objects are configured to be stored in the file-system on the primary server and credit card numbers are stored in session objects, the application may violate PCI-DSS standards for storing PAN (primary account number) in clear text.

As far as the programmers are concerned, they are just storing the data in a session object without realizing that the data is ending up on the file system. In situations such as these, you may need to consider encrypting the data that is being stored in the session object.

4. Use short session timeout intervals
The session timeout interval is usually configured on the server, although most platforms provide API to manipulate using code. This controls the amount of time a session will stay alive in case there is no activity in the session. The shorter the interval, the lesser the time that an attacker gets to guess the session-id.

5. Use a session-id with sufficient entropy and length
Most built-in session frameworks use a sufficiently random (entropy is the degree of randomness) session-id that are long enough that they cannot be predicted. This is one of the reasons for recommending using built-in session frameworks above. If the application generates its own session-ids, ensure that the session-ids meet these criteria.

6. Invalidate sessions on the server
A lot of applications just clear the cookie that contains the session-id when a user logs out. This does not kill the session on the server. If the session-id is replayed by a malicious user before the session times out, the malicious user can gain control of the session. API calls such as Session.Abandon() (ASP, .Net) or session.invalidate (J2EE) should be used to kill the session on the server when a user logs out.

7. Regenerate session-id when privilege changes
The session-id should be regenerated whenever the user’s privilege changes. For instance, when the user logs in. This will prevent session fixation attacks against your application. Session-ids should also be regenerated when a user moves from HTTP to HTTPS and vice versa.

8. Set the secure and HTTPOnly flags on cookies
Remember to set the “secure” attribute for cookies. This will ensure that those cookies are sent only over SSL/TLS (HTTPS connections).

Setting the HTTPOnly attribute will prevent client side scripts from accessing the cookie and its value. This will prevent cross site scripting attacks from stealing session tokens stored in cookies. The path and domain attribute should also be set appropriately.

You can find more information on cookies and their attributes in the article titled “Understanding cookies” on this site. Also check out how to protect cookies by restricting scope.

9. Do not use/reuse session-ids for any other purpose
Session-ids are random identifiers assigned by the application server to uniquely identify and compartmentalize users. They should not be used as cryptographic keys or to create unique file names. Using them for other purposes may result in session-ids being exposed. They should also not be re-assigned to another after a user has logged out to prevent replay attacks.

10. Use valid SSL certificates
SSL/TLS certificates use by any application should be valid. When users get accustomed to accepting invalid certs, they become vulnerable to accepting certificates provided by malicious users. This can result in MITM (Man in the middle) attacks.

11. Regenerate Session-Ids when switching between HTTP and HTTPS
It is a very good idea to regenerate the session-id when switching between HTTP and HTTPS urls on the same site. This will protect against attacks such as session hijacking and session fixation.

Note that you may need to persist the data already stored in the session variables to local variables on the server and then reassign them to session variables once the new session-id has been generated by the server.