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

1

6

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

Pistole answered 15/2, 2014 at 0:3 Comment(1)
I bet the hackers don't know any of this: seclab.web.cs.illinois.edu/wp-content/uploads/2011/03/…Kalil
A
2

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.

Auxiliaries answered 16/2, 2014 at 17:29 Comment(4)
Right -- But is it safe to use Facebook's manual login flow with the internal redirect_url? This does not require the app secret. Furthermore, is there a way to use a chrome-extension:// url as the redirect_url? Would this be secure?Pistole
There is no way to use a chrome-extension url as a callback url. If you think about it, it makes intuitive sense. If you give facebook the the url chrome-extension://abcdefghijklmnopqrstuvwxyz/index.html , which only makes sense in the context of your local machine, facebook would have no way of resolving that address and sending it anywhere meaningful. If you wanted to, you could spin up a server on a random open port to listen for facebook's response, and use yourip:port as the callback url (note don't actually do this). But then you'd run into issues with firewalls, permissions, etcAuxiliaries
Note that is still not secure. Once a user has granted your application access to their data, it is your responsibility as a developer to ensure that only your application has access to said data. As long as you rely on any form of client side authentication, a malicious user can spoof your client's requests and gain access to said data using your app's credentials.Auxiliaries
Facebook could definitely redirect to a local URL, and in the case of a chrome-extension URL -- this should be guaranteed to call desired extension code, since Chrome extension IDs are generated from the developer's private key, and are unique. Hacking the Chrome browser is outside the scope of this question. I am concerned about allowing Facebook login without participation from my own server, which would seem to allow spammers to post "via" my application to compromised accounts. All Facebook apps allowing API access from "*" would be vulnerable.Pistole

© 2022 - 2024 — McMap. All rights reserved.