Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android facebook-sdk signature security

We've been implementing the Facebook Android SDK in our android app which requires to store the app signature on the facebook server so calls from the app to facebook can be validated. We'd like to use this system for our own backend to make sure it's only being used by our app and regarding to this I have the following questions:

(Refer to https://github.com/facebook/facebook-android-sdk/tree/master/facebook/src/com/facebook/android to find the related classes)

  1. Obviously, to validate the call by matching signatures, the app's signature needs to be sent to the server. Within the sdk, I cannot seem to find where this is done?
  2. It seems no https is used, is that correct? (Util.java)
  3. Couldn't the signature be sniffed rendering this whole system pointless?
  4. Facebook.java holds the facebook app's signature at the bottom of the file. It might seem trivial to change this. However as far as I understand the signature of an app that sends an Intent can be resolved via that Intent. The Android system manages this and therefore a signature cannot be faked. However when calling an url can the Android system add the signature to the protocol in such a way it is immutable? I guess not, which makes me wonder about above questions.

[Edit in reply to nitzan & zapl]

What I'm trying to achieve is the same as why the facebook sdk requires you to store the signature on their server; making sure calls to our backend are sent from our app and nothing else. We don't want to allow bots or other apps to access our server api. The facebook sdk has methods to check if Intents originate from the Facebook app, which is safe because of the closed management of signatures and Intents by the Android system. The only way to compromise this would be by running a modified Android version which allows for overriding app signatures but the odds of people building and running that are neglectible. However running an app, sniffing the signature that is sent over a non https protocol and building an app that uses this signature with api calls isn't. It seems the only way to make such a system work is using https, which it seems the facebook sdk doesn't.

Note that the Intent validation methods I'm describing above is different from the url calls to the facebook server. The Intents are used to have the Facebook app on a device communicate with an app which implements the SDK. The Android system ensures the signature of the Facebook app that is sent with the incoming Intent cannot be faked so the Facebook app->app communication system is safe. As opposed to this internal system my question is about the external system of outgoing url calls to a server which would be safe if the signature could be sent immutable along the call, basically implementing the same system as the Intent system.

[edit 2]

As opposed to what we were assuming, it turns out an app signature is easily fetched. While apps need to be signed using a private developer key this doesn't compromise security concerning apps on Android, however it obviously cannot be used to validate api calls serverside.

This leads to more questions:

  1. Why is Facebook implementing this system while it's easily compromised?
  2. Are there any other known implementations to restrict server api access to a specific app only? (other than obfuscation)
like image 945
Will Kru Avatar asked Feb 22 '26 02:02

Will Kru


1 Answers

  1. I don't know.
  2. Yes, it seems to be replacing an fbconnect:// Uri with http:// meaning there is no encryption for connections using this code.
  3. I guess yes, try it to verify that.
  4. It is no problem to change that, you can decompile apks change some code and compile them back if you want. The only thing that you can't do then is to sign the apk again (you lack the secret key required for that). Or you can use the signature in your own code.
    The signature check for your app happens at installation time and during that permissions you request in your manifest are removed if your signature does not match the requirements. If you update your apk the signature of the new apk is checked against the old existing apk and the upgrade will fail if signatures don't match. But you can deinstall the old one and install your fake one.
    If you send and Intent from your app the system probably includes the package of the sender and you have no access to change that.

And the whole point of verification to the server is not ultimately a security thing since there is no bulletproof way to authenticate an app. It is used to make it harder for others to abuse the API and it is used to track who is using the api.

An authentication mechanism requires that there is some sort of secret key inside your apk. But since you ship that apk to potentially evil customers you have no more control over it and it is possible to extract the key and abuse it. All you can do is to obfuscate the key so it is harder to get it. But it is ultimately not possible.


So let's assume you have an app out there that communicates with your backend server and I download your app to my device. I can then get the .apk off my device, decompile it and find how the communication with your server works - the plaintext before https is ever created. I can also see what the signature of your app is, that is stored in an xml file on the device and in the apk as well. Then I go an either modify your app or create a new one that uses the information to behave exactly as yours would do with the exception that it is not your app. It's no problem to use https and I can also send you your expected signature.

You can't prevent that from happening. You can only make it hard to do that.

like image 180
zapl Avatar answered Feb 24 '26 18:02

zapl



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!