canjs / can-connect-feathers

The FeathersJS client library for DoneJS and can-connect
https://canjs.com/doc/can-connect-feathers.html
MIT License
10 stars 4 forks source link

Work out how to get login/logout events working securely in Feathers #21

Closed marshallswain closed 7 years ago

marshallswain commented 7 years ago

We can take advantage of the realtime socket events to handle sessions. We don't want to broadcast the event to everybody in some apps, so we need to be able to secure it.

marshallswain commented 7 years ago

For initial login, securing the login/logout events to the current socket connection is problematic. If we consider that we have two pages:

  1. the main app page
  2. the OAuth popup -> Success redirect page.

Before we authenticate the user, we don't have a method of marking the socket connections as belonging to the user. So when we get successful auth on the "success redirect" page, we can't target the main app page because its socket is still anonymous.

marshallswain commented 7 years ago

We might be able to make this happen if we setup a way of authenticating anonymous users.

  1. On first visit, the client calls authenticate with no params.
  2. The server:
    • creates a unique identifier for the unauthenticated user
    • Encodes it in a token
    • Sends it back to the client
  3. The client stores it in the feathers-jwt cookie
  4. The user opens the login with GitHub button & the Github auth popup opens
  5. User successfully authenticates with GitHub
    • There's a problem here, because this will overwrite the "anonymous user" token in the cookie.
  6. Before creating a cookie for the new token, the server checks for an existing token/cookie and sends the login event to any socket.io connection containing the anonymous user inside the cookie. The main app page will receive this notification and can update its stored token.
  7. Server creates the new cookie.
  8. Server redirects user to the /auth/success page.
  9. The /auth/success page closes itself
ekryski commented 7 years ago

@marshallswain can you not just:

  1. pop open window
  2. do the oauth dance
  3. callback to parent window with token parsed from either cookie or querystring
  4. authenticate the socket in the parent window with the token

You shouldn't have to try and notify the socket in the parent window from server to client that they are authenticatd.

marshallswain commented 7 years ago

@ekryski That's what I was originally looking at doing, but I couldn't figure out how to get a reference to the parent window again after all of the redirects.

ekryski commented 7 years ago

Did you look at how Auth0 does it in their lock repo?

marshallswain commented 7 years ago

Nope. Good idea.

marshallswain commented 7 years ago

There's a potential CSRF-related security concern with trusting the cookie, but I believe the likelihood of being able to pull it off is close to impossible as long as XSS attacks are properly avoided. The perpetrator, at domain attacker.com would have to open a socket connection to the API server after the anonymous user token has been created. This would then allow the socket connection from attacker.com to receive the new auth information.

But really, if there's an XSS issue on the page, why not just skim the token from localStorage or the cookie.

marshallswain commented 7 years ago

Closing this for now. This might be a priority in the future, but I have the OAuth popups working, now, without this.