Search code examples
facebookoauthoauth-2.0facebook-oauth

How is native client only Facebook Login secure if you never send your client secret to get an access token?


When you integrate Facebook Login into your app, there are essentially 2 (OK, there are more than 2, but for this question I'm just concerned with these 2) ways to get an access token:

  1. Have FB return a code to your app, which you then exchange for an access token ON YOUR SERVER by adding your client secret. The client makes a call like this, https://www.facebook.com/dialog/oauth?client_id=APP_ID&redirect_uri=REDIRECT_URI&response_type=code , and then the server handling the redirect URI passes the code and client secret onto FB to get an access token.
  2. Have FB return an auth token DIRECTLY to your app in the redirect URL: https://www.facebook.com/dialog/oauth?client_id=APP_ID&redirect_uri=REDIRECT_URI&response_type=token . In that case, the token is returned directly to the client in a URL fragment.

(Above info taken from https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow/v2.2 )

Thus, my question is how is the second method, where FB returns a token directly, secure when you never had to prove the client is who he says he is? Do the tokens returned in the second case have fewer permissions than the first case? I know on the web, by default clients get short lived (e.g. 2 hour tokens), but if you use the Android or iOS SDKs, you get long lived tokens, even though you never pass a client secret. Thus, related question is how can the Facebook Android and iOS SDKs be really sure that the client app is who it says it is (the client app can always be disassembled and someone can steal any information you ship with in the app)?

Fundamentally I'm trying to understand how oauth flows that send a token directly to the client, without requiring any sort of server-side protected secret, can be secure.


Solution

  • It is a less secure way of transporting access tokens to clients. The OAuth spec acknowledges that explicitly in section 10.3 (https://www.rfc-editor.org/rfc/rfc6749#section-10.3) and more so in section 10.16 (https://www.rfc-editor.org/rfc/rfc6749#section-10.16).

    The point of that last section is that you indeed cannot trust that the Resource Owner really gave you the access token, so you must never expose more information through your client other than the information that the access token allows you to access.

    Note that the party that gave you the access token apparently could get hold of that information on its own since it got hold of the access token, so there's no issue in disclosing that information through your client. Just don't assume that it is the Resource Owner that you're exposing to.

    The implicit flow is secure in the scope of the OAuth specification - delegated access control, it cannot be used to authenticate users.