WordPress Core Proposal: Session Management

When you log in to WordPress, the platform should record the event, where it occurred from, and the device that was used. This would empower you to kill off rogue sessions if necessary.

First, let me explain what I mean by “session.” I’m not talking about regular sessions in PHP – for those I’ve already built WP_Session, and I’m quite happy with the direction that project has taken.

Instead, I’m referring to actual activity sessions – periods of activity for which you are logged in to the site.

Security

Ideally, whenever you log in to WordPress, it would record a new authenticated session, identifying you, the time you logged in, the device from which you logged in, and the physical location of your session. This would give visibility into the various machines capable of accessing your account – i.e. machines where you clicked “Remember Me” while logging in.

Once you can see your sessions, you can easily kill off rogue ones. Say you logged in at a public library (bad idea in the first place) and forgot to log out before you went home. Being able to log in, identify the still-open library session, and kill it before a random passer-by finds and abuses your site would be a huge win.

Facebook, ironically, already implements such a security model. From the Account Security page, you can see a list of all of the locations from which you’re logged in and, if necessary, can revoke access to any of those locations.

Discrete list of all of the locations from which I'm currently logged-in to Facebook
Discrete list of all of the locations from which I’m currently logged-in to Facebook

Drawbacks

There are two primary failings of this system. First and foremost, is data storage. We could very easily just store this information in a custom post type as it’s not necessarily meant to be queryable. Alternatively, we could also store it in user meta, since it is user-specific. The question becomes: how do we actually track, and negate, active sessions?

WordPress would have to track not just nonces, but some sort of session ID for each logged-in user (which could become a very large set in some circumstances). We’d then have to check if that session ID is in a known list of closed sessions – a list we’d have to retain for as long as we allow cookies to be valid (which can be a very long time in some situations).

Secondly, while Facebook can track mobile apps, WordPress wouldn’t be able to. WordPress’ mobile apps send your username and password on every single request, meaning there isn’t a persistent session that can be locked out.[ref]If someone were to find my phone and bypass the laughable security built-in to Android, they’d have unfettered access to this site. For that reason, I refuse to log in to WordPress.com-hosted sites from my phone at all.[/ref] Incidentally, this is why securing both your password and your username is a huge deal.

Proposal

For now, let’s leave off XML-RPC. I’ve already proposed a solution for further securing that access (which would dovetail nicely with controlling session access). Instead, let’s look towards administrative control of logged-in sessions.

My gut tells me that adding a custom table for user sessions would be a good idea – but for a minimum-viable product, let’s store things in usermeta. Every login gets a new entry that records a session ID (also recorded in the [cci]wordpress_logged_in[/cci] cookie). Every invalidated session ID is stored in a second usermeta collection against which we check when providing access for administrators.

Yes, there will be a little added overhead to admin-side requests. I’m willing to trade a bit on speed in favor of increased security, though.

Would you take a different approach?