32

Say I have a RESTful web service and a commercial Android app on the front end which is used to interact with it. I may use SSL so that the endpoints are not visible, but someone could still do some reverse engineering to find them.

I could also use SOAP instead, so that the call to the web service is a bit more complicated. But, I still don't know if this gives me any real advantage over RESTful based service.

I was thinking about hardcoding the key into my client app, so that only my client app could use the service. Also, maybe some code obfuscation may help. But, how much does this really help?

UPDATE: As JOW pointed out Fiddler

could be used to decrypt https and see the full request. However, if I use Android app only, this may be solved by hardcoding server certificate in Android client app. And also, there is SOAP WS-Security, but I guess a tool can be made to function in similar way as fidler to circumvent that.

Ana Mandic
  • 371
  • 4
  • 6
  • 13
    It's quite trivial to unzip your apk to replace your hard coded server certificate, which will allow network capture tools like Fiddler/pcap/wireshark to MITM the connection. Trying to prevent unauthorized client application is a waste of time, always put authentication on the API. – Lie Ryan Mar 22 '17 at 01:32
  • Is it important that only your app is used or that only the users that you know have an account on your webservice can use it via any app? Because some people gave answers with the latter in mind, and I'm not sure that's what you meant. Please clarify. There's a chance OP might wanna restrict their webservice only to their own app because they wanna show only their ads and only provide their official user experience, and not let anyone else create an app with their ads or some bad UX. – user1306322 Mar 22 '17 at 02:50
  • 46
    By making a client app so good nobody will want to use anything else? –  Mar 22 '17 at 04:26
  • @jasonszhao Unless of course the point is your client is intentionally hobbled. For example the official client only displays half the entities on the map, or does not display entities that are occluded by walls, or requires the user to manually identify and compute trajectories to other entities... – Aron Mar 22 '17 at 05:32
  • 3
    You could sic lawyers on anyone who tried it, but that's a recipe for annoying your users and losing market share. Just ask ICQ. – Michael Hampton Mar 22 '17 at 05:37
  • 7
    I've deleted my answer. It was marked down because people wanted me to answer the literal question, rather than help solve the problem. In short, authenticate the user, not the client. – Tim Mar 22 '17 at 06:35
  • 2
    Anything on client side is untrusted. You can only make it difficult by Obfuscating your client side code as well as communication. But a determined Person with resources can still emulate your client. – AEonAX Mar 22 '17 at 06:51
  • Tinder has been trying to do this exact thing for years and they have failed. – JonathanReez Mar 22 '17 at 09:51
  • 3
    Can I ask why you want to do this? While it's not possible in the general case, there may be some arrangement that can still meet your underlying goals. e.g. if you want to force people to spend $0.99 on the app store, just having some simple obfuscation would probably be enough. – paj28 Mar 22 '17 at 10:07
  • 1
    This is the problem Snapchat is desperately trying to solve... and yet a quick search for "snap upload" yields multiple third-party clients. The only solution is to not make a crappy client in the first place as to give no valid reason for third-parties to make their own. – André Borie Mar 22 '17 at 10:22
  • @Aron Why would you run a game with a RESTful API? – JAB Mar 22 '17 at 15:09
  • @Jab for any sort of api – Aron Mar 22 '17 at 15:10

8 Answers8

42

This would be impossible. It is fundamental for your app to contain all the instructions necessary to use your API. Anyone with enough skill and time will be able to extract these secrets and create their own client.

Justin Gerhardt
  • 371
  • 2
  • 7
  • This is incorrect. Have a look at my answer. – Tim Mar 22 '17 at 00:51
  • 14
    @Tim if the app is available in the store and is able to talk to the service, people can download the app, observe its network traffic, and mimic whatever it does (such as authenticating) in their own client. Justin has it quite correct. – CBHacking Mar 22 '17 at 00:59
  • 2
    I guess this is the right answer to the question asked. I don't think the question asked is quite the right question. You usually want to restrict access to information, rather than the access method. – Tim Mar 22 '17 at 01:16
  • If Google offered the service, wouldn't it be possible for the app to use the google account to provide a token to the server that the server could verify with Google? – Nathan Merrill Mar 22 '17 at 16:01
  • Wouldn't you need to have access to the source code of the app? What if the communication keys were encrypted using a key in the app's source? – Noah Broyles Oct 28 '21 at 20:03
24

It’s pretty easy and straightforward to create one’s own client regardless of whether REST or SOAP is used, as long as your Existing Client is available for everyone in the Play Store. Just capture the HTTP traffic from an Android device using Fiddler, and engineer your own client based on the captured traffic.

Even HTTPS traffic can be easily decrypted using Fiddler. The HTTP Methods, URLs, Headers, Cookies, Body and your Key are all visible. I don’t think this is secure at all. (There are other reverse proxies out there that can do the same as Fiddler.)

TRiG
  • 609
  • 5
  • 14
JOW
  • 2,319
  • 2
  • 16
  • 24
  • But, will Fiddler be able to intercept the traffic if I have just an Android app, and not a web app? I didn't find any app like Fiddler for Android, and I don't know if setting it up on PC as a proxy in my local network would work. Also, I could hardcode server certificate in my android app. And what about SOAP WS-Security? – Ana Mandic Mar 22 '17 at 00:36
  • 3
    Yes it can. Check out my first link. – JOW Mar 22 '17 at 00:48
  • 8
    @AnaMandic So many ways to do it. With fiddler no less. There are more options if we don't restrict ourselves to fiddler. I could put the Android phone on a hub/forwarding switch/router. I could put the Android on a VM. I could replace the JVM https module to send clear text. etc etc – Aron Mar 22 '17 at 05:19
17

From a security perspective, no, there's no way to do this. No matter how much obfuscation you put on the code and protocols, the fact is that the code to access the API and the network traffic produced when the API is accessed is in the hands of your users, and they can use whatever reverse-engineering tools they want on it.

From a business perspective, you need to evaluate the cost to you if someone produces an alternative client against the extra cost to implement measures to prevent that from happening. For example, you could use a heavily-obfuscated proprietary API (avoiding REST, SOAP, and other standardised protocols) entirely, but this will be more difficult for you to implement and therefore cost more. On the other hand, it would make it considerably more difficult for someone to reverse-engineer. You need to work out if such measures (or other appropriate measures) are worth it to your business.

From a legal perspective, a lot of places have terms of service that prohibit the production or use of third-party clients. It's up to you to enforce that by monitoring traffic to your server to determine if one is likely to be using a third-party client, or by watching for the appearance of third-party clients on app stores. It's also up to you to decide if you have the resources to take legal action, and if it's worthwhile for you to take such action.

From a user-relations perspective, you may want to reconsider the idea of prohibiting all third-party clients as a blanket rule. Obviously nobody wants a developer to produce a horrible client with their own advertising, but a lot of services these days allow third-party developers to register their applications and receive an API key. The process of registering can be as simple or as complex as you want, ranging from a simple terms of use (e.g. "don't put your own adverts in the app") to an evaluation of their interface or a full examination of their source code (of course, the simpler it is, the more willing developers are going to be to sign up). Allowing third-party developers to use your API isn't necessarily a bad thing either - they might want to produce an app that uses your service as a data source but isn't related to it in any way, and in that case they could actually bring you more business if they put proper accreditation in their app, or they may want to fill a market that your business has no intention of going into, or they may truly have a better idea for a client app for your service, which is something you can learn from to improve your own app.

Micheal Johnson
  • 1,746
  • 1
  • 10
  • 14
4

You can't make unauthorized access to the API impossible in the security sense, but you can minimize it. It's not really a security question but the concept of the threat model is pretty appropriate: Who do you want to prevent from accessing your API, and what kind of damage do you want to avoid?

Many large websites forbid alternative means of access to their service, usually so they can continue to serve ads. They do so through a combination of measures at many levels:

  • checking the request headers and user agent (which stops great numbers of casual ordinary users)
  • complicating the API by adding dynamic state, obfuscation and other measures (which stops casual reverse-engineering, but not the determined)
  • forbidding it in their Terms of Service (which stops other legitimate businesses, and a few conscientious individuals)
  • enforcing the ToS through lawyering (which may be necessary against unethical businesses, but will do more harm than good if deployed against small-scale individual users.)

None of these are 100% effective, but they don't need to be. The important thing is that they cut down on loss. Think about what you want to accomplish, and choose your countermeasures accordingly.

alexis
  • 321
  • 1
  • 5
0

Say I have a RESTful web service and a commercial Android app on the front end which is used to interact with it. I may use SSL so that the endpoints are not visible, but someone could still do some reverse engineering to find them.

SSL does not conceal the target IP address, so they don't even need to reverse engineer anything. Everything else can be obtained via Fiddler + MITM certificate.

I could also use SOAP instead, so that the call to the web service is a bit more complicated. But, I still don't know if this gives me any real advantage over RESTful based service.

Well, the more effort you put in, the more effort a hacker will need to put in, I suppose.

That being said, hackers have a lot more free time than you, and there are a lot of them, and only one of them has to post the solution on a bulletin board and it's game over.

So, probably not worth the effort.

I was thinking about hardcoding the key into my client app, so that only my client app could use the service. Also, maybe some code obfuscation may help. But, how much does this really help?

Hackers now have deobfuscation tools at their fingertips, so it doesn't help as much as it used to.

Probably not worth the effort.

Fiddler could be used to decrypt https and see the full request. However, if I use Android app only, this may be solved by hardcoding server certificate in Android client app. And also, there is SOAP WS-Security, but I guess a tool can be made to function in similar way as fidler to circumvent that.

The hacker could reverse engineer all that much faster than you could build it.

So, probably not worth the effort.

You can't stop a hacker from reverse engineering any code that runs on the client. So whatever safeguards you put in, the hacker can imitate them.

Exactly. Don't spend time on this.

Instead, try to design your application so sensitive features are executed on the server, where you can protect it.

Spend the rest of your time improving the features of your app so customers won't want anything else.

John Wu
  • 9,101
  • 1
  • 28
  • 39
-3

You want to :

prevent someone from making his own client app for my webservice

You want your webservice to identify your app on user devices before further interactions, this seems impossible as you have no guarantee on the integrity of the app which could be altered with reverse engineering.

You may want to consider reviewing the architecture of your solution.

elsadek
  • 1,782
  • 2
  • 17
  • 53
-5

Yes, this can be done, though of course there are no perfect solution.

You would need to add encryption and message authentication to both client and server. Both negotiate a session key based on a shared secret, possibly with the addition of a unique client ID. There's plenty of documentation around on how to do that (keywords: session key, key exchange, API key). The key to this system is that the communication is encrypted and signed with the session keys, not with the actual key (aka shared secret). This way, the real key never travels the wire and cannot be intercepted.

An attacker could still reverse-engineer your client to extract the shared secret and the mechanism for deriving the session key from it. But this requires higher skills then simply listening to some REST chatter.

Tom
  • 10,124
  • 18
  • 51
  • 18
    "An attacker could still reverse-engineer your client to extract the shared secret" = "No, this can't be done", NOT "yes, this can be done". – Oleg V. Volkov Mar 22 '17 at 09:55
  • 1
    Reverse-engineering requires higher skills, but there are many people with the required skills out there. And if **ONE** of your users does the job, they can spread the knowledge to everyone else. – Stig Hemmer Mar 22 '17 at 11:15
  • @OlegV.Volkov - I stand by "yes". You can make the process of extracting the secret reasonably complex, definitely enough to thwart most attackers. It all depends on your threat model, of course. But from the information given, it doesn't seem the questioner is up against government entities. It's a solid, commonly used approach with reasonable effort that provides adequate protection against most threats. – Tom Mar 22 '17 at 12:28
  • @StigHemmer - knowledge does not magically spread. Even if someone successfully reverse-engineered the app, someone looking to write his own client is not guaranteed to find that information. Other than cracked software, this kind of data will not be on a well-known torrent site. It will stop most people from implementing their own client, it will not stop the most dedicated attacker, but then again, if you're up against the NSA or the Chinese Mafia, you need better security advise than stackexchange. :-) – Tom Mar 22 '17 at 12:29
  • 1
    @Tom, im am a decent Java Developer and that is the core knowledge which is needed to Develop a Android Application. And with the given Tools (Android Studio from Google/IntelliJ ) I can take the App, put it into my IDE and have fun to read every line you try to do in cleartext. – Serverfrog Mar 22 '17 at 13:32
  • @Serverfrog so I don't need to point you to ProGuard and other techniques to make reverse-engineering of Android Apps more difficult? Something as simple as whatever the Java equivalent to JS minify is throws out the vast majority of people, who either lack the skill or don't want to spend the time. – Tom Mar 22 '17 at 16:56
  • @Tom if someone want to, he can. That is all Security through obscurity. Nothing more or less – Serverfrog Mar 22 '17 at 16:57
  • @Serverfrog That's like saying "don't put a lock on the front door of your house, bulldozers have been invented so if someone really wants in, they will". Security isn't binary like that. And I recommend you put that lock. – Tom Mar 22 '17 at 17:05
  • @Tom but if the Question is: can someone request to my webinterface if I release a Android App the answer is yes. If the Question would be "can I make it harder that someone could send requests", then your answer would be correct. And the thing ProGuard etc. is that doesn't hide the URL's that are used for the Request so its more: a running Bulldozer stand in front of the door. If someone is on your Ground and he want to break in he can do it very easy. – Serverfrog Mar 22 '17 at 17:10
  • Right. I see I can't explain the point I'm making. Just every App that cares about securing its requests is doing it exactly like this. I gave Google keywords in the first response, do your own research, guys. – Tom Mar 23 '17 at 07:59
  • Just realized the top-voted answer to the duplicate question is saying what I'm saying. So I'm outta here. *facepalm* – Tom Mar 23 '17 at 08:01
-6

The only guaranteed why to stop unwanted usage is to perform some form of user authentication. Such as requiring the user of your app providing a username and password each time they start the app and passing this to the server. If the server validates the user it would return a session token that has to be used in all subsequent API calls. However, it might be that your application is not suited to making users login.

Without the login it will always be possible for someone with access to your API because they can reverse engineer your code and/or snoop the data to pass back and forth. So your aim is to make it as difficult as possible for someone to reverse engineer your code and API. Make sure you do not provide a fixed value from the client to the server. That is simple to find and then use in alternate client.

Instead you want to generate a new code each time you login to your server so that every time someone snoops the traffic they see a different value and they cannot simply replay that value. This forces them to reverse engineer your code to discover the algorithm used to generate the key. Put some effort into making that code hard to understand and so replicate.

  • 6
    This is not a solution. If anyone has a username and password for the original app, they could easily use them to make their own client app - which is exactly what the OP is trying to avoid. – MiaoHatola Mar 22 '17 at 06:35