Why an Facebook/Twitter app has to need 2 keys? - facebook

I'm developing an mobile app on the iPhone.
After creating an app on Facebook/Twitter, I received 2 keys:
Facebook call them as app ID and app Secret
Twitter call them as consumer Key and consumer Secret
When I use OAuth authorization as some tutorials on Google, my app must provide both keys to proceed. I'm confused as to why it needs 2 keys. As their names (id and secret), I guess that their roles is equal to public/private keys pair in Linux. But I must provide both 2 keys so that my app proceeds.
I want to place the secret key in my own Apache/PHP server, the secret place, not in my app's code. My app is only responsible for authorization, then my server proceed with other tasks, as posting,...

The app id and consumer key are identifiers of your app. The secret is what you share with the service provider in order to authenticate requests and such. Like a username (identifier) and password (secret).
The secret must not be shared - this is in the developer policies. Doing so would allow other to access the data of your app users which would obviously be a serious privacy breach. So you are right to plan on keeping it out of sight. Your app id is publicly available to anyone, so you can put that where you want/need.

AppID is used for authentication, appSecrect is used for other tasks.
Consider these two documents of Facebook and Twitter about authentication for web app for more detail:
http://developers.facebook.com/docs/guides/web/#login
https://dev.twitter.com/docs/auth/oauth
Consider this flow for an implementation Facebook/Twitter app on mobile if you have an own server for the secret:
OAuth Twitter with only Consumer Key (not use Consumer Secret) on iPhone and android

Related

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

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.

Can my web service api call facebook/google oauth2 on behalf of another web service?

I'm building a web service for use as an api component in web sites or apps built by others.
I am building a set of functionality that my clients can use on their sites for their users, but which are served by my application.
One of these services is user login. I intend to support multiple types of logins, and provide the client application a user token once the user is logged in. So the client application only has to implement one login interface, but they get a variety of oauth2 strategies for it.
To make this work with their google or facebook accounts, they would have to provide my app with their application id and secret key. Entering a secret key on someone else's site, even for integrating with your own site seems dangerous. They call it a "secret" key for a reason.
I have found one web service which seems to be doing something similar to what I am planning to do:
https://www.authic.com/documentation/google_oauth2
They have a configuration page for client accounts where the user enters oauth2 credentials to enable the Authic oauth2 login pages on behalf of the client app.
What are the security concerns to be aware of with this kind of service, and can the client app use a service like this safely? If it can be used safely, what is required for safe use? I think the app doing the oauth2 interface would be able to do other things on behalf of the client app, since it has an app secret, and the client app owners would have to trust that this was not happening.
The alternative to this strategy seems to be using my own application id with oauth2, and having the client apps redirect to my app's login page. Then the user will see the oauth2 permissions page with my app's logo instead of the app they were intending to log in to.

Secure rest api with 3rd party login provider

I've got a web app that currently allows users to login via Facebook. This is the only login mechanism at present. I make use of the user id and the users friends to perform certain actions. Now I want to create an api that I can use to create a native mobile app. To do this, I would need to authenticate users against the api. I've looked at this question
Possible approach to secure a Rest API endpoints using Facebook OAuth
but I don't actually have a "user" table as I only pull the facebook info when I need it. In iOS or something similar I could obviously make use of the native facebook sdk and then call my api, passing in the required user id and friend ids etc. however I'm not sure then how I could specifically secure my api so that if a user got hold of another's user_id they could in theory retrieve info via the api or in theory any resource that only specific users should be able to see
I thought about creating an app_id and app_secret for all the separate apps consuming the api. I would then use the appropriate secret to encrypt the data being sent and returned. The api and native app would know the secret and be able to decrypt it and validate that a user can view the requested resource. Does this sounds like a valid approach? In theory only the native apps would then be able to decrypt what is returned from the api. Or should this really be done on a user by user basis as recommended in the linked post?
All of this would be done over https
Thanks
Not familiar with the Facebook API nor iOS so I am speaking completely in theoretical terms.
Could you not:
Ask the user to login with Facebook on the iOS app
Send the login data over a secure channel to your web application to handle the actual processing of the data
Send the iOS app a secure hash for authentication
Use your web application as needed; using the hash for authentication, make HTTPS requests as you would your web application and use the responses from the webserver to populate the iOS app
If you make a user_hash column a complex salted hash like a SHA-256 (or greater) hash, the user_hash will become invalid before anybody is able to guess the hash. You could save the user's Facebook credentials locally on the iOS device and then renew the hash every so often, as to invalidate old hashes and lock out perpetrators (like how a cookie expires). If the user hash somehow becomes invalidated while using the iOS app, the app will send the locally stored credentials and retrieve a new one.
If Apple offers cookies for apps, you could send the hash in a cookie from your webpage and give it a reasonable expiry time (e.g. 1 day). You'd be resending the locally stored Facebook credentials every day and be effectively locking out anybody trying to bruteforce your hashes. Use that instead of trying to implement cookies from scratch (if the iOS API offers that), but as I said, I'm unfamiliar with iOS.
From an SQL standpoint, your webpage would validate a user's Facebook credentials, create a new row with a randomly generated user_hash, expires timestamp, user_id, friends_id, etc. Every user that uses the webpage will have to send the user_hash either from their web-client or the iOS app and will be checked against the database. If the present timestamp exceeds the expires timestamp, the session is ruled invalid and the user cannot operate your application.
Of course, you'd need to encrypt the communication. Do you pass credentials everytime the user loads a page on your web app? Or do you store them in a session?
Hope this helps at least somewhat!
https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSHTTPCookieStorage_Class/Reference/Reference.html

Developer left, How do I recover my App?

How can I get hold of an App where the only Developer with Admin Access is not reachable? Can I recover and administrate the App using my App Id and Secret Key?
I think that's a problem, because you can only add a role to an existing app via the Graph API if you have a User Access Token of one of the administrators of this app:
https://developers.facebook.com/docs/graph-api/reference/app#roles
An App Access Token (which you could generate with App Id and App Secret) is not enough.

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.