views:

138

answers:

5

In a client-server application how can the server know that a request comes from a genuine application and not from a tampered copy of it? I still haven't developed neither the client nor the server application. The solution may be plain socket, wcf, IIS hosted or whatever.

+5  A: 

There really isn't a way. Anything you could ask for the app to provide, a rogue app could spoof. Ultimately the answer is that you shouldn't trust any client application. You can trust users provided they've authenticated, but the client itself is 100% untrustworthy.

To illustrate this completely, I could run all of the traffic through a proxy server and inject/remove messages at will. Then you've got a legitimate client with spurious messages.

Now if you're talking about a library that you plan on using on a client, making sure it hasn't been tampered with, that's what strong naming assemblies is for. But that wouldn't help you over the wire.

Hounshell
+2  A: 

You can't "guarantee" that you're using a real client. There really are no "secrets" in computers; only facts that are made more difficult to discover. Some things that can make it more likely that your client is the real deal are:

  • Authentication. Digital signatures, internal hashes, and data provided by the user all make it more likely that what you're talking to is what you think you're talking to. However, programs can be hijacked by malicious software that uses your client assembly as a puppet. Even if there are no publicly-accessible hooks to your code, a piece of malware or a hack that acquires permission to run with SkipVerification can reflect into your assembly and invoke private members.

  • Security monitoring. Clients you create can periodically ask Windows about who currently has memory hooks into its code. If someone is listening to your client, or using it, that your client doesn't recognize or that the server has identified as hostile, the client can crash and burn and the server knows that that client has been compromised. This is generally hard to work around, but knowledge of the security procedure can help to compromise it by either working fast to avoid security "patrols", or by hijacking your client's hooks into Windows to ask about suspicious activity.

  • Behavior monitoring. If a client starts sending messages that don't make sense, or doesn't send a "still here, still sane" message to you every so often as you expect, the server can detect that there's something wrong with the client and treat it as suspicious, either ignoring it completely or restricting sensitive data. Again, knowing what the client should be sending, or piggybacking on the client, can allow an attacker to spoof expected behavior.

KeithS
+2  A: 

Many companies ensure there's a trust channel between a client and server by deploying digital certificates at each end (called mutual or 2-way authentication). It's practically impossible to spy on or spoof any communications between apps that have enabled mutual authentication.

Of-course, this only secures the channel, but not the client app itself. The only way to ensure that the client is completely tamper-proof is to involve implement physical security controls that protect the running application (ie. ATMs and POS machines).

Simon@LabSlice

Simon Ellis
+1  A: 

I agree with Hounshell's comments in that all data on the web should be treated as untrusted. There are however steps you can do to increase the complexities of a required attack and prevent easy tampering of the client, such as with strong names as suggested. Authenticode certificates can also offer protection against tampering of code and to ensure software from a particular source is genuine.

You could also implement authentication between client and server, whereby authentication is based on data known only by a user (not written into the code). This circumvents the usefulness in tampering with a client as an attacker can't really achieve much without the necessary credentials to validate against the server. To accomplish an attack they would then need to either intercept data in transit, or install something on a users machine (at which point it's game over anyway).

To protect data in transit from data snooping (man-in-the-middle) attacks you need to encrypt the data. This can be achieved with SSL communication between client and server, provided some basic checks are performed. The client should ensure the certificate is signed by a trusted root CA, has not expired, and is issued against the URL matching the one being called.

TheCodeKing
You have to use the right security technology for the right job. Strong names are **absolutely positively not designed for authenticating clients**, so **do not use them for that**. Strong names are designed for helping *users* make trust decisions about *applications installed on their machines*, not to help *servers* make trust decisions about *clients*. Using security technology for a purpose that it was not intended for is worse than using no security technology at all; using it wrong produces a *false* sense of security, which is worse than a *correct* sense that security is weak.
Eric Lippert
Totally agreed - the suggestion of strong names is to prevent tampering on the client that could facilitate an attack on the server. It by no means makes the communication with server any more trusted, however it's another link in the chain to improving security and raising the levels of required effort in an attack.
TheCodeKing
+1  A: 

You cannot authenticate applications remotely.

You can authenticate users, and you can prevent man-in-the-middle attacks. But if you think the authenticated user himself/herself is hostile and might tamper with the application, then there is no way to stop that from happening.

Your best bet is to validate all of the inputs, reserve critical pieces for operation on the server, log all activity for each authenticated user, and limit as much as possible the damage that a user can cause to or through your system.

Jeffrey L Whitledge