109

SO and SU just told me I've been logged in. I'm guessing because I'm already logged into my Google account... but how does SO know that?

2
  • 1
    long talks but nobody explains me why in 2015 this auto-login still doesn't happen.
    – sorin
    Feb 14, 2015 at 9:19
  • @sorin: Really? This bar never appears? What browser are you using?
    – mpen
    Feb 15, 2015 at 23:12

2 Answers 2

172
+200

I'm going to provide more than just the technical details here, as I think there are a lot of implicit assumptions about global login that aren't quite correct out there.

Accordingly, this is going to be really long.


Design Requirements

  1. A user having logged into any SE-site will be automatically logged into every other SE-site on which they have an account
  2. Site level logins must not fail if the global login system is down
  3. Must not present unexpected sites or information to the user
  4. Must not degrade the anonymous user experience

1 is obvious, 2 is due to a strong desire not to introduce a new network wide dependency, 3 is shorthand for "don't scare off the user," and 4 is an acknowledgement of how much of our traffic is from anonymous users.

These are taken as axiomatic, any scheme that didn't fulfill all 4 was immediately discarded.

The Scheme

Initial Login

  1. Login as normal (unmodified code path)
  2. At the end, the user is given a global login token (attached as a cookie)
  3. The next page the user visits takes that token, and (via an IFrame) shovels it to StackAuth (stackauth.com)
  4. StackAuth verifies the token, and attaches a session key via localStorage

Visiting a New Site

  1. User hits any page on the site
  2. Some javascript hits StackAuth via an IFrame
  3. StackAuth checks localStorage for a session, and sends it to itself if it is.
  4. StackAuth validates the session, and (if valid) passes a login token to the SE-site via postMessage
  5. The SE-site validates the token, looks up the user, and (if valid, and the user is found) logs the user in

Some Technical Details

  • Every step that passes data between the SE-site and StackAuth (I3, V2) uses a one-time-use request token to prevent XSRF attacks.
  • All tokens are opaque to the user (more details below)
  • The entire Visiting a New Site process is suppressed on a site after it is run once in a browser session.
  • The idea is that once it has failed, the user is probably anonymous and it'd be a waste to keep trying. We allow users to force a login attempt by clicking "log in" to work around edge cases.
  • This also implies that if you visit one site, then log in on another, and then go back to the first, you'll need to click "log in" to trigger the process.
  • To see if your system meets all requirements, see the Network Login Troubleshooting page.

Tokens

  • Request Token Contains
  • The requesting site
  • The IP for which it is valid
  • Login Token Contains
  • The generating site
  • The destination site
  • The actual login credentials (roughly equivalent to the user's OpenId)

Crypto

Security Discussion

We're in a pretty novel position, as we cannot trust the user despite acting on their behalf. Conceptually, we have two of our sites (some StackExchange site, and StackAuth) communicating using the user's browser as the channel and as a data store. Accordingly, everything that passes through the user's browser (which is everything, really) must be cryptographically secure.

Acknowledging this, we turned paranoia up to 11 and went full on "defense in depth*." If anything looks "weird" we bail, and the user degrades to using manual logins.

Things We Check

  • Your HTTP Referrer is one of our sites
  • Your IP has been held constant between subsequent requests to the SE-site and StackAuth
  • The sites encoded in the tokens are correct
  • The tokens are no older than X minutes (its really tight, but subject to change)
  • Nonces are never reused

Third-Party Cookies, SSL, and More

Some responses (on the blog, and elsewhere) ask why we don't just use cookies (or cookies set via images, IFrames, script tags, link tags, etc.). These are all third-party cookie schemes, and they just plain don't work. Trust me, everything that's been suggested thus far was actually tried at some point and found lacking.

With some song and dance you can get Chrome, Firefox, and IE to accept third party cookies (most of the time anyway). Safari requires that you set these cookies via an IFrame, and convince the user to interact with it; which is quite possibly the suckiest user experience you can come up with for a global login scheme. A browser as popular as Safari just plain not working with any third-party cookie scheme just kills the entire technology for us.

There have been some SSL questions. The short of it: we don't use SSL anywhere in global login. SSL protects against man in the middle attacks between the user's browser and a website. As noted above, we don't trust the user so SSL doesn't actually solve any of our security problems. Also, currently our normal user session cookies (usr on StackOverflow, for example) aren't sent over SSL; any attack against global login would work equally well once a user is logged in "normally". Naturally, if we switch to SSL across the sites we'll do the same in global login but right now it'd be pointless. SSL also imposes non-trivial performance penalties.

Inquiries have been made about open-sourcing our implementation of this scheme, or allowing third-parties to authenticate users with it. In short: no. This scheme makes very hard assumptions about how a site works, and thus isn't easily open source-able. For third-party authentication, I'd much rather use something more "standard" like OAuth2.0 (which isn't acceptable for us in network, since it assumes a many-to-one consumers-to-providers scheme).

*The idea is that an attacker has to jump through a lot of non-trivial hoops before they can even start to attack the actual cryptographic system.

30
  • 1
    Nice! But the sole fact that it works actually scares me a bit; I hope Local Storage is not going to be abused just like the Flash Local Shared Objects, aka Flash-cookies, are being abused for tracking. (And just like third-party cookies were abused, and then got some protection.)
    – Arjan
    Sep 12, 2010 at 9:42
  • @Arjan - meh, in my opinion the entire problem is intractable. If you want to include third-party content on a website, you have to trust the third-parties in question. Sep 12, 2010 at 10:01
  • True, but as a visitor it's the first-party website I need to trust in making the right judgement then. I'm not a PC, but IE's internet zone idea seems to allow for trusting first-party websites, which can then include whatever third-party content they wish? Sounds good, but I never saw (nor searched for) similar ideas in other browsers. As a result of my laziness: sorry to say I blocked third-party cookies and Flash LSOs (surely not perfect). I really hope Local Storage does not get abused; I like what you built! :-)
    – Arjan
    Sep 12, 2010 at 11:45
  • 1
    @Arjan - the onus is definitely on the first-party site, we're in complete agreement. Sep 12, 2010 at 12:10
  • Thanks for the info, it's very insightful. Although I confess I'm not sure i understand the use of iFrames and how it fits it. I would appreciate more information around this if possible. thanks.
    – Ash M
    Sep 13, 2010 at 1:00
  • IFrames are necessary to get javascript running under a StackAuth's "context." Simply including the javascript (via a script tag, or similar) would cause all localStorage access to occur under the SE-site's domain. Sep 13, 2010 at 2:17
  • Can third party websites check for the token's mere existence?
    – badp
    Sep 13, 2010 at 18:40
  • @badp - no. This scheme is not meant for third-parties in any way. Third party authentication will be part of some later API version, presumably. Sep 13, 2010 at 18:46
  • @Kevin, I'm not asking if third parties are supposed to use it. I'm just asking if the mere existence of the token can be detected, say, by advertisement companies.
    – badp
    Sep 13, 2010 at 22:28
  • 1
    @badp - no, only code originating from StackAuth can read the token. The token is also a random string, it doesn't contain any user identifying information; its used to lookup that information in a database. Sep 13, 2010 at 22:56
  • 1
    Thank you for sharing this information with us. Many sites would prefer to keep these types of details secret (security through obscurity. right? RIGHT?) But this was a very interesting read and very informative from a development perspective.
    – Matt
    Sep 23, 2010 at 22:07
  • 7
    @Matt - even if we wanted to use obscurity as part of our defense in depth (an approach which isn't entirely without merit... just nearly so, in my opinion), we run a site frequented by a talented pool of professional developers. It'd take a day, maybe two, before most of these details were reverse engineered by someone. Plus, we like talking about our clever hacks :) Sep 23, 2010 at 23:02
  • @Kevin which postMessage are you referring to, the DOM one or the Windows API one? If the DOM one, how does the SE window send the credentials to the SE server?
    – Falkayn
    Dec 21, 2010 at 22:39
  • 1
    When 3rd party cookies are disabled in Chrome, LocalStorage in the iframe fails with "SecurityError: Access to 'localStorage' is denied for this document." The Chrome option is named "Block third-party cookies and site data" -- likely the "site data" portion of that refers to local/session storage. The Stackoverflow "Network Login Troubleshooting" page also reports "Storage" as failing. In contrast, LocalStorage in Firefox works when 3rd party cookies are disabled.
    – Ben Amada
    Nov 24, 2013 at 7:33
  • 1
    @Kevin with the login going through a major overhaul, time to update this answer, no? Dec 21, 2015 at 9:17
18

They are using HTML 5 Local Storage. Jeff happened to publish a blog article just today, describing what happens behind the scenes:

6
  • 1
    Sweet! Thanks. But can you also explain how HTML 5/local storage is not programming related?
    – mpen
    Sep 12, 2010 at 0:37
  • @Mark: I didn't vote for the migration. It fits on both sites in my opinion. Maybe those who voted for migration thought that you'd get better answers here :) Sep 12, 2010 at 3:38
  • 1
    So... I read through both articles. I don't see a significant advantage of localStorage over cookies. We get 5 MB instead of 4 kB and a tiny bit of "added security" because the data is kept local and not sent with every request, and "speed" for the same reason. But, presumably, you need to send some login key when the user visits the page anyway, which is presumably encrypted and validated in either case. And speed... we're sending maybe 100 fewer bytes of data... which is all great and a step in the right direction, but its still only supported in the newer browsers.
    – mpen
    Sep 12, 2010 at 4:39
  • I'm also not sure why they opted to store everything as strings.. only to shortly after try to standardize some typed storages such as SQL or IndexedDB. But now I'm getting into the merits of localStorage.
    – mpen
    Sep 12, 2010 at 4:41
  • By "encrypted" I mean probably some kind of hash, but with localStorage or cookies, they could both be intercepted when it tries to log you in, no? Unless we're using SSL. You can't just SSL the "ajax" call that transmits the login info, can you?
    – mpen
    Sep 12, 2010 at 4:45
  • This is good option, this doesn't effect SEO but will IFrame work from https to http sites ? because some of our domains are in http please advice.
    – Shaiju T
    Jan 11, 2017 at 18:13

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .