Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to validate the origin of a web service invokation

Suppose you have a mobile application (Windows Phone or Android) that connects yo your back-end using SOAP.

For making it easy, let's say that we have a Web Service implemented in C#. The server exposes the following method:

[WebMethod]
public string SayHallo() { return "Hallo Client"; }

From the server perspective, you can't tell if the caller is your mobile application or a developer trying to debug your web service or a hacker trying to reverse engineer/exploit your back-end.

How can one identify that the origin of the web service call is THE application? as anyone with the WSDL can invoke the WS.

I know I can implement some standard security measures to the web service like:

  • Implement HTTPS on the server so messages travel encrypted and the danger of eavesdropping is reduced.
  • Sign the requests on the client-side using a digest/hashing algorithm, validate the signature in the server and reject the messages that have not been signed correctly.
  • Write custom headers in the HTTP request. Anyways headers can be simulated.

However, any well experienced hacker or a developer who knows the signing algorithm, could still generate a well signed, well, formatted message. Or a really good hacker could disassemble the application and get access to the hidden know-how of my "top secret" communications protocol.

Any ideas how to make the SayHallo() method to answer ONLY to request made from my mobile application?

We are running in the context of a mobile application, with hardware access, there could be something that can be done exploiting the hardware capabilities.

If someone wonders, I'm thinking on how to make a mobile app secure enough for sensitive applications like banking, for example.

Thanks for your ideas.

like image 236
Adrian Salazar Avatar asked Dec 24 '12 15:12

Adrian Salazar


4 Answers

What you are describing is bi-directional authentication. It can only be done by storing a signed public key (certificate) on boths sides of the communication. Meaning that each app would need to authenticate your server with your servers public key and the server would need to authenticate each instance of your app. The app's public key would need to be produced and stored on the server at the deployment time with each instance of your app. Think of this as 2 way HTTPS, in general the only authentication that needs to be done is one direction, with the browser authenticating the server with a trusted signing key. In your case this would need to be done on both sides. Normally you would have a service like VeriSign sign each instance of a public key, this can get quite spendy with multiple deployments of an app. In your case you could just create an in house signing application using something like OPENSSL to sign your app every time it is distributed. This does not mean that someone still could not hack your code and extract the signing key on the app side. In general any code can be hacked, it's just a question of how hard can you make it before they give up? If you were to go the custom hardware route, there are things such as crypto chips and TMP's that can serve as a key sotre and make it harder for people to gain access to the private keys on the device.

A quick google search turned up the following:

http://www.codeproject.com/Articles/326574/An-Introduction-to-Mutual-SSL-Authentication

If you are thinking about using rewards points, and are really worried about someone gaming the system from the outside a better solution is to have each person make an account that is stored securely on the server and their points are saved and tallied there. This centralizes all the data and allows you complete control over it with out worrying about a malicious app reporting non-existent points. (this is how banks work)

like image 144
Jimmy Johnson Avatar answered Oct 16 '22 07:10

Jimmy Johnson


If you want to verify that a user is both mobile and who they say they are then the best way is to leverage the network. Send a push notification with the hashed key that you want the user to use via:

  • APN for iOS

  • something like urban airship for windows phone

  • GCM for Android.

like image 38
ERR0 Avatar answered Oct 16 '22 08:10

ERR0


In general, the model looks like:

  • Server authenticates itself to the many clients with a certified public key (this is the whole Public Key Infrastructure, Certificate Authorities, etc)
  • Each client identifies itself to the server via some other authentication system (in 99.9% of cases, this is a password)

So if you're wondering how this sort of thing works in the case of banking apps, etc that's basically how it breaks down: (1) Client and server establish a secure channel such as a shared secret key, using the server's public key, (2) Client authenticates via this secure channel using some other mechanism.

Your question specifically, however, seems more aimed at the app authenticating itself (i.e., any request from your app is authentic) with the thought that if only your app can be authenticated, and your app is well-behaved, then everything should be safe. This has a few implications:

  • This implies that every user of your app is trusted. In security terms, they are part of your "trusted computing base".
  • Attempting to achieve this sort of goal WITHOUT considering the user/user's computing platform as trusted is essentially the goal of DRM; and while it's good enough to save money for music publishers, it's nowhere close to good enough for something really sensitive.

In general:

  • The problem that you're specifically looking at is VERY hard to solve, if you're looking for very strong security properties.
  • You likely don't need to solve that problem.
  • If you give us some more context, we might be able to give you more specific advice.
like image 39
mfsiega Avatar answered Oct 16 '22 08:10

mfsiega


In addition to the answers already given, how about using a login type scheme with the unique id of the phone and a password? Get the user to register with your "back-end" and every time a transaction has to be made with the back-end, require the password or have an option to automatically log in.

like image 29
PmanAce Avatar answered Oct 16 '22 08:10

PmanAce