Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The correct way to OAuth from a desktop client without a server

I am working on an extension which must connect with Facebook to download some user data. I am somewhat new to the details of the OAuth dance, and have not been able to implement this with a desired level of security. In the current setup (which works) I am concerned about evildoers hijacking my application's name and using it to post spam.

I have tried many different techniques to implement OAuth (Login With Facebook in particular) in my extension. The current setup uses Facebook's Manual Login flow.

  1. Open OAuth popup window in sandboxed tab.
  2. Set redirect_url to special, internal facebook page which does not require configured redirect URLs, set the auth_token parameter to return an auth_token, not temp code.
  3. Inject javascript into the special redirect page which posts a message to the extension with the auth_token.

This works as expected. I am able to retrieve user auth_tokens after they give my app permission via popup.

I am concerned about security since the extension does not have a server to store a secret key, nor does it have a valid domain to limit redirect_urls and verify the authenticity of authorization requests. Due to this flow: a hacker could simply download the source to my extension, steal the Facebook App ID, generate popup windows for my app from their own websites, and obtain auth_tokens which can post on behalf "via" my application.

Even more concerning, the official Google Chrome gudie to OAuth in Extensions recommends embedding your consumer_secret in the extension. This seems counter-intuitive.

I am reasonably confident this can be solved in two ways:

  1. Creating my own server which acts as a proxy between my extension and Facebook. I could set the redirect_url to my custom domain, store the consumer_secret on my server, and define a narrow API between the client and my own server.
  2. Restrict the authorization redirect to my Chrome Extension ID (sort of like how Facebook iOS SDK uses App store bundle identifiers). Unfortunately, I can not associate my Facebook app with a Chrome extension ID. It says "invalid URL."

I would prefer the 2nd option, as running a server can be costly and introduces another point of failure for the extension. Users also have to deal with "black box" code holding their auth_tokens, which sucks.

Interestingly, it looks like Facebook makes special exception for ms-app:// URLs (Windows 8 applications). Why not chrome-extension:// urls?

So my question: -- Is this possible? Am I missing something? Secondly: Am I being paranoid about this type of hijacking attack? It seems fairly benign, but I would rather not allow hackers to hijack my app's oauth dialog.

Thank You

like image 238
Jordan P Avatar asked Feb 15 '14 00:02

Jordan P


1 Answers

Your intuition is correct. According to facebook's developer doc's:

Never include your App Secret in client-side or decompilable code.

The reason for this is exactly what you said, even in compiled, obfuscated byte code, it is fairly trivial using modern methods to reverse engineer the app secret, even if you are using https.

The best practice in this situation would be to have a hosted api that would be used to proxy all logins through an external source, and to hide your app id and app secret in a separate config file.

like image 115
Hans Z Avatar answered Sep 30 '22 10:09

Hans Z