Doesn't Xamarin.Auth 1.3 work securely with Facebook OAuth? - facebook

Facebook documentation states that
the App Secret or an App Access token should never be included in any
code that could be accessed by anyone other than a developer of the
app. This applies to all methods of code that are not secured like
client-side code (such as HTML or Javascript) or native apps (such as
iOS, Android or Windows desktop apps) that could be decompiled. https://developers.facebook.com/docs/facebook-login/security#appsecret
For this reason, if your 'App Type' under Advanced Settings in the App
Dashboard is set to Native/Desktop we assume that your native app
contains the App Secret or an App Access Token in the binary, and we
do not allow calls signed with an App Access Token to proceed. The API
will behave as though no access token was provided.
Therefore if you embed App Secret in your app and tell Facebook about it, it will simply stop working with OAuth (I have also tested this, when you check that option, Facebook stops validating the secret).
but Xamarin.Auth 1.3 (latest stable) requires clientSecret (in OAuth2Authenticator class clientSecret is the required parameter) and uses it to obtain Facebook access token when user successfully logs in.
So is it a bug, is there a workaround, or Xamarin.Auth is useless with Facebook for now?

OAuth2Authenticator contains multiple constructors and there is one that does not require ClientSecret:
public OAuth2Authenticator (string clientId, string scope, Uri authorizeUrl, Uri redirectUrl, GetUsernameAsyncFunc getUsernameAsync = null)
This one will allow OAuth2 Implicit flow and thus does not need a client secret to be stored within your application's code.
Ref: https://github.com/xamarin/Xamarin.Auth/blob/9c19d90e52994188def9e12e0bbc981a3943a752/src/Xamarin.Auth/OAuth2Authenticator.cs#L110

Let's not confuse things. This has nothing to do with Xamarin.Auth.
There are two major options for OAuth2:
Implicit flow
Authorization code flow
The implicit flow does not require a client secret. The implicit flow is typically used with mobile apps, since they cannot keep a secret (you could disassemble the app binary and find the secret). Same goes with Javascript or desktop apps. The only way to protect the secret is if it is stored on a server which cannot be accessed by third parties (=the users).
The authorization code flow uses the client secret as an additional protection, the secret identifies a specific party, like a server.
So what does Facebook state? They say, if you configure your app to be a native/desktop app in Facebook's dashboard, they assume (!) that you store the secret in the binary, because: where else would it go? As a consequence, the secret is no longer a real secret, hence the Facebook API acts as if the secret was not there.
Two solutions:
Either you configure your app as not native/desktop (I don't know which term Facebook uses, maybe "Server")
or you use the implicit flow which was designed for mobile clients.
And to answer your initial question: yes, Xamarin.Auth supports Facebook's OAuth2, because it is just like any other OAuth2.

Related

OAuth 2.0 protocol in native Apps, e.g. Instagram

I am currently building an API for my native App and want to implement the OAuth 2.0 protocol for authentication. If I take a look at companies like Instagram, Facebook or Twitter I wonder how they are handling the authentication process of their own native App (not third-party).
So Instagram for example is using the OAuth 2.0 protocol to protect their API endpoints (here). Related to their developer platform they offer you - as a third-party developer - the possibility to use their API and authenticate your own App via Server-side (Explicit) or Implicit flow. All of these flows require the user to authenticate via an In-App browser (or system browser).
Like I said before, I am wondering how these Apps are handling the authentication in their own Apps. The user doesn't get redirected to any browser to authenticate. They could use the Explicit flow and store the client_id and client_secret for example in Keychain (iOS). But Instagram is telling third-party developers "You should never pass or store your client_id secret onto a client. For these situations there is the Implicit Authentication Flow.".
I don't want the user to get redirected in my own App. The user should be able to use a login/signup form within the native App.
Does anyone have an idea or insides on how Instagram etc. are doing it? I am really curious and appreciate any helpful answer. :)

Spoofing facebook app ID

Following up on the design outlined in Design for Facebook authentication in an iOS app that also accesses a secured web service, and specifically the concern listed in https://stackoverflow.com/a/12912616/5154090: what would be the mitigation?
Specifically, I have a web server that exposes a REST API which is consumed by a mobile app. I'd like users to authenticate to the server (via the app) using Facebook.
Now, an apparently common flow is for the app to redirect the user to Facebook, where they will login with their credentials. The app will then get a token which it will send to the server, and the server will validate the token using the graph API.
But how can the server make sure that the token really came from the app? Specifically, what's to prevent a malicious app vendor from re-using my app ID? After all, the app ID is hardcoded into the app and can therefore be extracted and used by a malicious app. If users log into that malicious app with Facebook, then the malicious vendor can get tokens with my app ID and can impersonate users of my service.
How can one protect against this?
To summarize for anyone else who happens to contemplate this - there is indeed no way to prevent the client ID from being spoofed. This is one reason that developers are discouraged from using the OAuth implicit flow in native apps as pointed out by Andre D in https://stackoverflow.com/a/17439317/5154090:
the use of the Implicit Flow with native apps is NOT
RECOMMENDED.
(see https://datatracker.ietf.org/doc/html/draft-ietf-oauth-native-apps-09#section-8.5).
In practice, if anyone mounts this attack, then the user will download App A (a malicious app) and will then be asked to authorize App B to make actions on their behalf. As far as I can tell, this is generally the only indication that an attack is taking place.

how do they differentiate between internal and external application using Oauth2

Suppose I have a Web Service API defined and would like to implement OAuth Server to provide access to third-party mobile application and my own mobile application.
As these two types of application(internal/external) will try to access my API, what are the possible mechanisms that my authentication server differentiate them?
As an Example, Consider a Facebook app and Lyft (External).While login to facebook through Lyft, fb recognizes it as third-party app and ask for permission level but in Facebook(Internal) app they don't ask permission level. How do they do it?
*Please correct me, if I am wrong here.
OAuth 2.0 differentiates between clients/applications by granting them their own set of client credentials in the form of an identifier and a shared key, respectively named client_id and client_secret.

Is it possible to send a request to the Facebook Graph API from client side without exposing our access token to the public?

My question is related to, but not exactly, this question.
I am currently working on a business directory Web site (similar to Yelp), in which businesses have their own pages. Let's call this app DIRECTORY_APP.
Businesses might want to have their latest Facebook status update shown on their pages hosted on our directory. Let's pretend we have a business named BIZ_1. The assumption is that those pages are public pages.
Apparently the Facebook Graph API can be used for this purpose. So I can send a request to Facebook to retrieve the latest status updates for BIZ_1:
https://graph.facebook.com/BIZ_1_PROFILE_ID/posts?
access_token=DIRECTORY_APP_ACCESS_TOKEN
&callback=callbackName
However, if I use this from the client side, our Web site's access token will be exposed to the public, so this is not a reasonable solution.
Now in the aforementioned question, Anatoly mentions that we can retrieve the access token by sending this request first:
https://graph.facebook.com/oauth/access_token?
client_id=YOUR_APP_ID&client_secret=YOUR_APP_SECRET
&grant_type=client_credentials
However if someone inspects the Network log, this will also expose our Web site's access token (is this correct or is this a different type of access token?). This solution also exposes our web site's app secret (is this safe?).
So to summarize, what's a safe way in which I can retrieve the latest status update of a Web page from client-side without asking the browsing user to first log in to Facebook?
I can retrieve the latest status update of a Web page from client-side without asking the browsing user to first log in to Facebook
You cant do that without login.
And I guess access token is not exposed.
Maybe the smart trick here is to use a social plugin. The Like Box will do what you want, without any issues. But, it's not greatly customizable. Even so, it's possible to get it looking nice on a page!
It also skips any login issues you mentioned.
I found the answer after some Googling. In short, the answer is no.
And here's an excerpt from Facebook:
Security Best Practices
App Secret and App Access Token
The App Secret is used in some of the Login flows to generate access tokens and the Secret itself is intended to secure usage of your App to only those that are trusted. The secret can be used to easily create an App Access Token which can make API requests on behalf of any user of the app, which makes it extremely important that an App Secret is not compromised.
Therefore the App Secret or an App Access token should never be included in any code that could be accessed by anyone other than a developer of the app. This applies to all methods of code that are not secured like client-side code (such as HTML or Javascript) or native apps (such as iOS, Android or Windows desktop apps) that could be decompiled.
We recommend that App Access Tokens should only be used directly from your app's servers in order to provide the best security. For native apps, we suggest that the app communicates with your own server and the server then makes the API requests to Facebook using the App Access Token. For this reason, if your 'App Type' under Advanced Settings in the App Dashboard is set to Native/Desktop we assume that your native app contains the App Secret or an App Access Token in the binary, and we do not allow calls signed with an App Access Token to proceed. The API will behave as though no access token was provided.
If your App Secret is compromised, you should reset it immediately in the Basic Settings of your App Dashboard.

Facebook oAuth Authentication Security

Using the JavaScript SDK and making a login request, once I receive the request response from Facebook that states the user is "Connected" ho can I be assured that this request was not hijacked?
Facebook provides an app secret for use in validating the response, but in the examples for authentication the app secret is never requested.
I am looking for further examples of using the JavaScript SDK or C# SDK to securely authenticate facebook users.
If I don't understand the app secret or oAuth correctly, please feel free to advise and explain why the app secret is not needed, but from the documentation I've read it sounds necessary.
The app secret is only used server-side to very that a response is authentic. It can't be used client-side (ie: in JavaScript) because that would require storing the app secret itself in your JavaScript code which would entirely defeat the purpose of the secret (ie., it would no longer be a secret).
So, yes, your JavaScript requests can be hijacked, but it doesn't really matter. As long as you use your secret for server-side requests (for example, updating a MySQL database) you should be fine.