How to validate the origin of a web service invoka

2019-02-08 08:15发布

问题:

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.

回答1:

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.



回答2:

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)



回答3:

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.


回答4:

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.



回答5:

You can use the following way to secure and to track your requests to server.

  1. You can force the mobile or web clients to send you a Custom Headers of the device type when accessing your webservice through REST methods

  2. Use basic http authentication by forcing each client to have their own username and passwords provided by you as a authorized webservice provider..

  3. If you need more advanced protection you can use OAuth 2.0 to secure your webservice.



回答6:

Since your originating app is going to be Android or Windows Phone apps, either one of them will be relatively easy for the wanna be hacker to debug. in any case you're going to be running the code on a machine that you have no control over so no ssl tricks or checking signing will solve your fundamental problem.

the only way you can combat threat from it is to NOT TRUST THE CLIENT. verify that the input coming from the clients is valid before acting on it if you're making a game - that it's accompanied by a valid security token etc.

in essence build your service so that it doesn't matter if the user is using an unofficial client.