views:

37

answers:

3

Hi guys,

I am faced with a WCF security scenario that isn't particularly well documented online.

I am developing a product licensing service in WCF that will be deployed along with our software (i.e. the service is running on the same PC as the client). This licensing service will be responsible for a number of things related to controlling use of our software and connecting to our remote licensing server for updates, revocations etc. Consequently it's not the kind of service I want spoofed, and I don't really want spoof clients communicating with it either.

As it's running on the same PC as the client can anyone suggest a security policy for this scenario? I'm particularly interested in authentication as most of the other security principles are straightforward. I'm reluctant to get into certificates if I can help it but as mutual authentication is a priority I'm beginning to think I may need to implement a custom 'challenge/verify' scheme between the service and client.

Any ideas? Thanks for reading.

Chris.

A: 

This is not a complete answer, but are you having the service bind on localhost?

Steven Sudit
Yes, it will be binding on the localhost. Still haven't really decided on the binding type. I was guessing either TCP or Named Pipes, but if the security policy requires it I will happily use HTTP.
Chris Chambers
Named pipes and sockets both use shared memory for IPC, so that shouldn't be the deciding factor. Pipes use filesystem security, which is powerful but complex. If you don't want/need that, use sockets.
Steven Sudit
I suspect I will use transport security for netTCP binding which will give me a sufficient level of message protection. But only if it will support the extra security configurations that are the subject of this question. There are so many security configurations it can be difficult to choose the right one for your particular scenario!
Chris Chambers
Taking a step back away from this detail, I have to agree with Mike Brown. These security modes are to prevent attacks by people sniffing your packets. If the user can run your WCF service under a debugger, none of this matters.
Steven Sudit
+1  A: 

My suggestion is that no matter how much effort you put into that, there will be an attack vector that makes all of your effort null and void. One option is to use ILMerge to provide a single dll for your entire application, and store it encrypted on disk and create a loader that hits your service passing in the registration information. On your side, the service will validate the customer information and send back a decryption key. The loader would use the decryption key to decrypt the DLL in memory and load it dynamically.

The shortcoming of this approach is that a determined cracker could debug your application and when the DLL is decrypted, write the unencrypted stream to disk. Your only means of retribution would be to place some kind of marker on the DLL so that you can identify who was responsible for breaking your copy protection and bring legal action if it's found open on the Internet.

Mike Brown
You are correct. So long as it's running on a machine that the user has admin rights to, there is no winning move here.
Steven Sudit
Some good thoughts there Mike, I may well be able to implement something along those lines.
Chris Chambers
A: 

As long as you're deploying this software to the client, then you cannot store any kind of key inside it without risking compromise. Even if you use certificates, you cannot hide them from the client while still making them visible to your application. And if you embed the key in the assembly itself then someone will just pop it open using Reflector.

Assuming you don't care about outright cracking (i.e. patching the assembly's code to simply bypass the license checks), then there's one and only one correct way to implement this type of security and that is to mimic the way a PKI works, by using a remote server exclusively.

In a PKI, when a server needs to validate a client via a certificate, it checks that certificate against the certificate authority's CRL. If the CRL reports that the certificate is revoked then it refuses access. If the CRL cannot be contacted then the certificate is considered invalid.

If you want to implement this scenario then you need 3 logical services but not in your current configuration. What you need is a remote licensing server, a client, and an application server. The application server can, theoretically, reside on the client, but the key aspect of this app server is that it performs license checks against the remote licensing service and handles all of the important application logic. That way, "spoofing" the server becomes an almost impossible task because a casual cracker would have to reverse-engineer the entire application in the process.

This is significantly less safe than making the application server a remote server, and may not offer many advantages over simply embedding remote security checks in the client itself and scrapping the local app/licensing server completely. But if you are determined to take this 3-tier approach then the aforementioned architecture would be the way to go.

Again, this is assuming that you aren't worried about "direct" cracking. If you are, then you'll have to read up on techniques specific to that particular attack vector, and understand that none of them are foolproof; they can only slow an attacker down, never stop him completely.

Aaronaught
Thanks for your thoughts. Useful information, although I suspect this might be a little too baroque for our situation. I think you summarized the whole problem up quite nicely with your last line.
Chris Chambers
@Chris: It's strange that you call it baroque. The idea of a local licensing server seems far more so to me. I really can't think of any means by which a licensing server that runs on the same machine as the client itself as a proxy to a remote licensing server could possibly do anything but weaken security - but if you find a way, let me know.
Aaronaught
The problem is that the WCF service that I'm developing needs to do more than just act as a proxy to the remote server. It will be responsible for managing local usage and license files/information, as the user cannot be permanently connected to the internet when using our software. When a connection is established to the remote server the service will refresh the license information and upload the usage files. We will insist upon a remote connection at least once a month but the rest of the time we need to operate in a licensed fashion but offline.
Chris Chambers
The only reason I say 'baroque' is that we aren't exactly a huge company and we aren't likely to be on the receiveing end of much (if any) hacking. I just want to make sure I've covered all of the reasonable bases.
Chris Chambers
@Chris: That all sounds good in theory but the problem is that it doesn't work. You can't safely store license keys or run an entire license server on a local client and have it be even a little bit secure. If the license server is running on a client machine then it *is the client* - there's not much sense in trying to logically separate it from the client software. The only instance in which I could see this having value is in a corporate installation where corporate IT would be using it to manage its own licenses.
Aaronaught
I take your point on that completely, but we have to work within the boundaries of our situation. The license files will be stored using alternate data streams and digitally signed by our remote server so any tampering will be recognised as soon as the unit goes online and the licenses are refreshed. We've just got to hope nobody can crack the software to prevent it from stopping running within the 30 day refresh period, hence the need to mutually authenticate the client and the service.
Chris Chambers