Page MenuHomePhabricator

Make the stored session id be a hash of the used session id to isolate them
Open, MediumPublic

Description

In T206010 there was some discussion about defense in depth measures against session stealing. In that proposal it was proposed to have a narrow interface so that mediawiki could not dump all sessions. But it was pointed out that that is probably an unrealistic attack strategy if the attacker can just create a new session for whatever user they want.

I'd like to propose that instead of directly storing the session id, we hmac the session id with $wgSecretKey. Thus making the link between the user cookie and the session data blob being one way.

This would be meant to prevent an attacker with the following capabilities from being able to impersonate other users:

  • Attacker does not have access to mediawiki's PrivateSettings.php, but can read and write arbitrary keys to the backing store for sessions.
  • Attacker had limited access to MediaWiki, but could not mount an active attack (perhaps time constraints or something) so decided to dump the session db and MW's secrets for later analysis and use in later attacks.

While these aren't the most pressing attack scenarios, given how easy this change would be with essentially no downsides, I think its worth it to do.

See also Tim's idea in T209556 to reduce risk around sensitive data stored in sessions.

Event Timeline

Wikimedia production has four different session providers: MediaWiki core, CentralAuth, OAuth, bot passwords. The first two use two different methods (session ID and user token); OAuth can be configured two work in two different ways (with or without cookie).

  • For MediaWiki core / CentralAuth session cookies this seems like a straightforward improvement. Implementing it would invalidate all sessions but for users who checked "Keep me logged in" the session would be recreated from the user token, so the impact is minimal.
  • For user tokens (core and CentralAuth) we do the opposite: the cookie is a HMAC of the DB value and a secret key ([[https://www.mediawiki.org/wiki/Manual:$wgAuthenticationTokenVersion|$wgAuthenticationTokenVersion]]). So attackers without private settings access already can't do much without them but in the limited access scenario (attacker steals secrets/globals and user token data from DB) the attacker can construct valid cookies. No helping that since unlike the session cookie it's unique per user and needs to be shared between devices.
  • Note that $wgAuthenticationTokenVersion was originally conceived as a non-secret version number (hence the name) and is documented as such, but per the discussion in T124440#2004414 we use it as a secret token. The installer still sets it to 1 though. Maybe that should be fixed. OAuth is an immutable providers (ie. all the data
  • Bot passwords will free-ride on changes to default session ID handling as they reuse that mechanism. They have their own DB token, which is always used in plaintext, but it is not sent to the user, only stored in the session data as a validity check. So not really useful to the attacker unless he already has the means to collect or create correct session cookie / session storage key pairs (in which case he can just attack the normal session anyway).
  • OAuth in non-cookie mode has deterministic session keys which can be calculated from publicly available data + the site secret. Guessing them is not really useful though since OAuth requests must pass the signature check regardless of whether the session data exists or not.
  • OAuth in cookie mode stores the session key in a cookie. It is fine to not HMAC that though, per above (the session is just for the benefit of the application logic, it is not an authentication mechanism).
sbassett triaged this task as Medium priority.Oct 4 2019, 5:25 PM