Usability and Session Expiration

So Alyssa IMs me in a rage this morning over something that I’ve long had a problem with myself. She was working at a student activities fair, and during some downtime, decided to write a post on the discussion board of one of her classes (a required weekly assignment). While she was writing it, however, a student came up to her table, so she had to stop and talk for a few minutes. When she returned to the computer, the session had expired and she had been automatically redirected to an error page, leaving her no way to save or retrieve her work.

I’ve said it before, and I’ll say it again: this is 2009, not 1994. There is no excuse for modern web apps to expire sessions without allowing you some way to save your work first. In fact, the whole usability model behind session expirations needs work. Let’s consider a few examples.

When it comes to sessions, there are basically two types of web apps: applications that don’t need sessions (some of which use them anyway), and applications that do need sessions. For applications that do need sessions, sessions must expire, that is a point I don’t wish to argue. However, they don’t need to expire the same way for every web app.

The most important reason for session expiration is security; some people will argue that performance also plays a role in it, and it does, but it’s a role that can be worked around with effective use of caching, compression, and collation (… erm, that is, sorting into a database, but I wanted the alliteration). However, there are different types of security that session expiration guards against — network security and “real-world” security — and not every application needs the same level of security, particularly at the expense of user experience.

Note: when I say “session,” I mean a set of variables specific to a particular user that are tracked across a visit to a website using some kind of session token or key. A “browsing session” is different: it more broadly means a visit to a website in general. A “browsing session” frequently triggers a “session” in many web apps; however, you’re engaging in a browsing session whenever you visit a website, while not all websites use sessions to track activity. I’ll use both terms, so I apologize in advance for any confusion.

Who needs sessions anyway?

When designing your web application, you should give careful consideration to whether or not you actually need sessions. Tracked sessions are really only useful when you have to maintain some kind of state across pages, or for some reason specific to your application, need to track how long a user is connected to your website.

That means that the vast majority of web applications don’t need to use session tracking. Applications with personally identifiable information, or the power to publish things on a user’s behalf, should pay close attention to the user’s browsing session, but the use of server-based state-keeping sessions is likely not particularly useful for most applications. A few applications where sessions might be useful include:

  • Survey applications (to keep track of answers from the previous page)
  • Chat applications (to reestablish open chats between page refreshes)
  • Hierarchical/drill-down applications, like fancy news readers and search engines (to remember where in the hierarchy the user is between pages)
  • “Headless” applications, like web services (to allow applications to make multiple requests without reauthenticating each time)

Don’t get me wrong, there are a lot of places sessions can be useful, but for the overwhelming majority of applications, there are other ways to track a small amount of state without incurring the overhead and security issues (eg, hijacking) presented by sessions.

But let’s say, for a moment, your application does need sessions. These sessions will have to expire, it’s neither practical nor safe to store session keys for an infinite amount of time except in very particular situations. You will now need to decide whether your application needs to safeguard only against network security issues (the case for most applications), or also against real-world security issues.

Real-World Security: Snoopers

Let’s say you log onto your highly-sensitive corporate email account from Widgets Incorporated on a public computer at your local Internet café. Just as you’re writing out a top secret status update to your boss, your decaf mocha latte is ready, and you’re forced to leave your computer, walk upstairs to the café counter, and pick up your drink. In the meantime, your rival from a competing company, who also happens to be in the café, walks over to your computer and reads the email. Congratulations, you just lost your company millions of dollars.

An unlikely scenario? Probably, but many web applications — whether they use sessions or not — have to keep a lock on the browsing session for fear of real-world security issues like snooping. Far more common is the issue where you log onto your email account or Facebook from a computer in a public library and forget to log off when you leave, meaning the next person who uses that computer has access to all your stuff. Thankfully, unless you were stupid and clicked “Remember Me,” that shouldn’t happen very frequently, but it is a legitimate concern.

For this kind of scenario, the best solution often doesn’t lie with sessions, but rather with the authentication mechanism: it lies with “Remember Me.” Rather than set sessions to expire after a given amount of time, simply set the cookie that identifies the session to expire when the browser window is closed. It solves the majority of real-world privacy issues as long as user agents (eg, web browsers) behave themselves and do what they’re told.

Let’s assume, though, that for some reason you do need to have time-based session expiration. Unfortunately, there are some instances where this is just going to cause problems, but you can at least take measures to mitigate issues.

For instance, the most annoying issue that arises from this problem is that of losing all of your hard work if you were typing an email, or a blog post, or a forum post, or what have you. With modern web browsers, this one’s an easy fix, and it’s disturbing that it hasn’t been implemented yet by most web applications. As I sit here and type this blog post, every time I pause for a few seconds, WordPress comes to my rescue and autosaves a draft of my work. That way, if there should suddenly be some cataclysm where my computer loses power, the next time I log back into WordPress from anywhere in the world, all of my work will still be there waiting for me. If your application developers are too inept to implement an autosave feature, at least allow users to manually save drafts so they can safeguard against losing information themselves. To quote a blog post I read earlier today, “Despite all rumors to the contrary, your users will not be dedicating their entire lives to using your web application in a punctual and timely manner.”

Network Security: Session Hijacking

Regardless of how strong a hold you need to keep on a user’s browsing session, if you use sessions to track state or authentication, you must — I repeat, must — safeguard against session hijacking. The easiest way to do this is to expire sessions when they’ve been idle for a long time (in addition to securing your connection with SSL), but that introduces the usability issues presented above.

However, let’s say that the real-world dangers for your type of application are minimal: for instance, it’s unlikely that your application will be used in such a way that users will open your application and then walk away from their computer (eg, administration panels, or your GitHub account) — applications where people usually log on for short periods of time, with directed purposes. The snoop factor is mitigated, so all we really have to worry about is session hijacking.

In other words, we’re saying that once a user logs on, they should stay logged on until they’re done working; session timeouts should not occur in this model. Sessions still need to expire, but they don’t need to expire if the website is still open on someone’s computer.

That same blog post that I alluded to earlier proposes a solution that I really like: a heartbeat. Using the power of Ajax, it is entirely reasonable for a website to send a heartbeat back to the server every so often to keep the session alive. When the heartbeat stops, the server can invalidate the session, but while the heartbeat’s going, that means the user’s still using the website (even if it’s sitting idle or the user stepped away from their computer), so that session can stay active. It’s a pretty simple fix to the problem that occurs when all your work is lost.

Even if a heartbeat isn’t a possibility, the user agent should try to keep track of the server session as best it can, and when a session is about to expire, it should notify the user in some way. If you aren’t concerned about real-world security issues, there is absolutely no reason to automatically redirect a user to an error page. Never, ever do that. Instead, display a small (but attention-grabbing) message at the top of the page that says “Your session may have expired, it is recommended that you backup your work on this page before attempting to save it” (or something to that effect but less confusing). That way, a user is given a chance (however kludgy) to save their work elsewhere (like in a Word document) before trying to post it, only to be told that their session expired a long time ago, and they need to recreate everything from scratch.

Reconciling the Two

One way of reconciling these two models of security that I’ve seen a lot recently is a radio toggle when you sign into a web application: Public Computer/Private Computer. If used correctly, that can then allow the web application to tailor its session security model to the environment in which it’s being used. If you log in on a public computer, it should make effective use of autosaving and automatically lock out a session when too long a period elapses. However, if you log in on a private computer, it could use a heartbeat to make sure you’re never logged out of a session unfairly. It’s a model that’s significantly underutilized, but it has a lot of potential.

Conclusion

Sessions can be incredibly useful, but just like you shouldn’t pound a nail into a wall with a shoe, you shouldn’t use sessions where a better tool can do the job. If a session must be used, however, don’t get so hung up in Fort Knox security that you forget to consider how the user views session expiration, it just makes your application look buggy and unprofessional.

As with all things, think about the user, and think about how your application will be used. The result will, quite simply, be something that doesn’t piss people off too much.

Comments

  1. The Voice of Reason

    The Voice of Reason said…

    Very good points *applause* I also don’t understand 1/2 of it, but that’s ok, cuz you do and I’m happy that sometimes people understand something important other than me.

    14 Nov 2009 at 5:21pm

Add a Comment