I came across a session management class in PHP which encrypts session data in the session storage folder (i.e., /tmp) and can be decrypted later in your script using a key. I was wondering if it's really needed? If you already doing some session hijacking prevention like this (simplified) example:


if (isset($_SESSION['fingerprint']))
    if ($_SESSION['fingerprint'] != md5($_SERVER['HTTP_USER_AGENT'].'SECRETSALT'))          
        exit; // prompt for password
    $_SESSION['fingerprint'] = md5($_SERVER['HTTP_USER_AGENT'].'SECRETSALT');

Do you still need to encrypt your session data? Or is encryption only needed if you are storing sensitive info via sessions (e.g., personal info, cc number, credentials) ?

Moreover, if you are validating whether a user is logged-in or not in a simple way like this:

// login.php

if ($_POST['password'] == $db_password)
    $_SESSION['logged_in'] = true;
    // show login again

// protected_area.php

if (!isset($_SESSION['logged_in']) OR !$_SESSION['logged_in'])
    exit; // prompt for password
    // show protected area

What damage can be done if session data is unencrypted and a hacker saw the data in plain sight (i.e., the md5 hash of the fingerprint and the logged_in = true). Can he actually log himself in or he must first "crack" the md5?

Note: md5 was used to simplify example, a much better hashing algo is used in real life.

  • @curiousguy What do you mean? If you mean /tmpthen /tmp is PHP's default session folder in a shared hosting environment. – IMB Aug 19 '12 at 18:08
  • Sorry I wasn't clear. Is /tmp written on disk storage? Is it a tmpfs filesystem? – curiousguy Aug 19 '12 at 18:10
  • @curiousguy I am not sure what tmpfs is but /tmp is usually just a regular folder in windows or linux. More info about it here: php.net/manual/en/… – IMB Aug 19 '12 at 19:10
  • 2
    I think IMB is talking about encrypting session data in $_SESSION so that attacks that read files in /tmp can't divulge user info. – Polynomial Aug 19 '12 at 19:55
  • @Polynomial That's exactly what I mean. Do you think it's necessary to encrypt it if you're not storing sensitive info in the session data? – IMB Aug 19 '12 at 20:23

You don't need to encrypt it. At most, encryption is a form of obfuscation. You're putting the key on the same system as the data, so it can always be found and extracted.

If you're set on encrypting it, it's actually quite possible to do it within PHP without modifying every use of $_SESSION. You can use the SessionHandler class to override normal handling of sessions. The documentation provides a simple explanation of how you can encrypt session data.

However, you'll need a way of creating and storing the key across the session. Obviously this can't be done through the session manager itself, otherwise you'd be distributing the key with the ciphertext. My suggestion would to be use an in-memory cache, such as APC or memcache, where the key name in the cache is the session ID.

  • Thanks, BTW here's an example of the script I'm talking about zimuel.it/en/encrypt-php-session-data it's unclear what's his purpose. Maybe he's storing sensitive info in sessions? He stores the key in the user cookie and encrypted data remains in /tmp (or the designated session path). Regardless, my question is more on why is it necessary to encrypt it? For example, if I don't encrypt data and if /tmp was compromised, an attacker really can't do anything with it right as long as there is session hijacking prevention? – IMB Aug 19 '12 at 20:48
  • They might still extract personal / sensitive information in $_SESSION, and session hijacking prevention isn't 100% effective. For example, if you lock sessions to IP addresses, an attacker could still steal the session from the same network as the user. It's a corner case, but if you're using the SessionHandler class there's almost no added complexity. – Polynomial Aug 19 '12 at 20:55
  • Ok you mention personal / sensitive information, so if I'm not storing this kind of info (i.e., I only store loggedin = true), then there's no need for encryption? – IMB Aug 19 '12 at 20:59
  • Sure, it's completely unnecessary in that case. – Polynomial Aug 19 '12 at 21:00
  • +1 It always bugs me when people want to add "encryption" to a system just because it sounds cool or it meets some compliance requirement. Encryption is -- at best -- only as secure as the key management. – Mark E. Haase Aug 21 '12 at 14:44

If you are using a reasonable web framework (one that has a halfway decent design), you do not need to encrypt session data. That really ought to be the responsibility of the framework.

However, if you are using PHP, you are not using a reasonable web framework. PHP is a problem child for security, in so many ways. One of those ways is that, by default, it stores session data in /tmp. On some shared hosting services, /tmp may be shared across users. So, PHP is storing session data in a location where others may be able to view it, without authorization. That is a bad design flaw -- but hey, PHP is full of bad design flaws, that's what life with PHP is like.

So, if you are using PHP on a shared hosting service (where /tmp is accessible to others), yes, you need to encrypt session data. One way to do that is to use the session_set_save_handler() hook to encrypt the session data. Make sure you use strong encryption (use authenticated encryption, avoid common crypto pitfalls) with good key management (for heaven's sake, don't store the crypto key in /tmp or anywhere else that other customers of your shared hosting service can see it).

Or, host your PHP application on a dedicated machine (e.g., a dedicated virtual machine; a VPS; a dedicated physical machine), and don't let anyone you don't trust log into that machine. Or, if you were somehow confident that you're not storing anything sensitive in the session store, you don't need to encrypt the session data (but this is fragile under maintenance, as it would be easy for someone else to add a feature in the future that happens to add some sensitive information to the session store without realizing the consequences for security).

But really, a better answer is: use a serious, well-designed web framework. Friends don't let friends use bare PHP for security-critical problems. See, e.g., Jeff Atwood's blog post on this topic.

  • 2
    So to summarize, there's NO need for encryption if there's NO sensitive info in session data, whether on shared hosting or private hosting. – IMB Aug 20 '12 at 12:51
  • 1
    @IMB, yes, that's correct. Thanks for boiling this down to a simple, clear rule of thumb! – D.W. Aug 20 '12 at 16:30
  • 1
    Any hosting company worth dealing with will have the Hardened PHP patch installed which encrypts the session content anyway transparently to the user, which renders a lot of your points somewhat moot. – SDC Aug 22 '12 at 8:51
  • 1
    @SDC besides "kindly asking them" is there a way to tell that a certain php setup has such a patch and be sure that potentially sensitive data is really encrypted in this magical "transparent way"? – humanityANDpeace Mar 17 '14 at 17:22
  • 1
    I think blaming this on PHP, and suggesting encryption as the solution, is a bit far-fetched. The problem surely is that the shared host is poorly configured such that users can easily read each other's data. PHP provides plenty of configuration variables the host should be setting to jail this data appropriately. – IMSoP Oct 12 '17 at 14:22

It doesn't make a lot of sense if the key is stored serverside - but the key might come from the browser / user. It's more dificult to access the key in this scenario (provided it's over SSL) even with some access to the server / source code.

Session data may be stored on the filesystem / in a database - and hence persist in backups. Also, on a shared system, depending how it is configured, this provides security-in-depth for session data - where one user account maps to one site, it's easy to restrict ssh / ftp access, but restricting PHPs access to specific directory trees is a bit more complex (there are some ways to get around open_base_dir); for low end hosting, it just doesn't make financial sense to run each webserver as a seperate uid / seperate FPM groups for each site.

While nobody in their right mind should be storing credit card details on such a system - what if you just want a simple front end for occassionally invoking other services - e.g. polling availability / performance of another server over ssh, sending an SMS, or accessing a mailbox? In these cases it's quite possible that you might temporarily keep a secondary authentication token / encryption key / remote session identifier inside the session.

While it's trivial to restrict write access to PHP src files to a small set of users other than the webserver uid, the webserver uid must be able to write session data. Once a user is authenticated, authorization is typically based on the authenticated user id stored in the session - hence this may be part of a solution to protect against privilege escalation (needs other components not mentioned in post).

It will help security in some edge cases depending on how the key is managed.

  • +1 the mentioning that the session data could for many reasons persist! Especially when PHP-sessions is used to store sensitive data encryption using a key directly implantet in the script would keep only accessible to the script, having access nonetheless. By ways of the servers/permission the session data might be more accessible/attackable then the script. – humanityANDpeace Mar 17 '14 at 17:10

It would be less complicated to use cookies to only store a session ID. The server must then remember which user belongs to which session, and which permissions each user has. This design has the disadvantage that it makes load balancing less effective because session data has to be communicated between all application instances.

A better design would be to let login nodes perform authentication and look up user permissions in the database. This data is then handed back to the client as a cryptographically signed token, which can be stored in a cookie or in a URL. Signing this token is required since encryption does not inhibit tampering with the token. It is critical then that each service verifies the signature before acting on it. This is actually the core idea between JSON Web Tokens

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.