Need help in protecting WCF service - c#

I'm developing a WCF Service and wnat to protect this service from unauthorized users. so i'm planning to add parameter "RSAKey" to the service and client (AddIn) will generate and sends the RSAKey with every request and Service will check passed RSAKey for that time for that IP and serves only if it is valid.
But my question here is, if some one decompiles the client (AddIn) though it is fuscated if he could guess of actual function that generating "RSAKey", he can call that method and generate RSAKey and use service without a problem.
So, is there anyway to protect my service to be consumed by valid/allowed clients?
Note:
one big thing to conside is, i want to distribute/give the clients freely for public usage without credentials. But same time want to protect from massive copy/miss usage of service.

Short answer: No.
The problem here is that your client needs to be able to connect. Anybody with a copy of your client and the time/knowledge to do it can figure out how it works, and make their own client that passes back the same thing. They're then free to do whatever they want.
A lot of money gets put into trying to accomplish this type of DRM by big companies, and it's always broken. Obscurity is the only real way this type of thing works (where nobody bothers to break it).
The service itself has to try and protect itself from misuse, either through authentication or through trying to sanity check the calls being made to block whatever it is you're trying to prevent. What you're trying to do isn't really very secure.
(What does this service do that you're so concerned about it, anyway?)

It sounds like your main concern is really "over-usage". If that's the case, then how about implementing some type of limitations on the client calls. You could:
-Limit the number of requests a client makes in a specified time period
-Limit the number of results returned in a single request
Of course, neither of these options will protect you over the long term. Given time, any client will still be able to download the entire DB via your service. By using some limitations, you're at least buying some time to analyze logs and determine if one of your clients is actually being malicious. By logging the requests to the service, it should be pretty easy to determine whether a specific client(s) is doing something evil.

Maybe you can host your WCF service by IIS server, then you can enable the https access and you can get the client IP address too. So you can suspend the access ip for a while if there is a suspected attack.

Leave the RSAKey generation out of the client application. Move it to one assembly that will be used both by site from which the client application is being downloaded and WCF service.
Provide RSAKey when user is about to download the client application. Save the {IP address, generated RSAKey} pair in store common to site from which the client application is being downloaded and WCF service.
Provide the ability to set the RSAKey for the client (so the RSAKey will be attached to each WCF message).
Inspect each message received by the WCF service in order to determine whether it contain RSAKey and whether the key is valid (search for existing {IP address, generated RSAKey} pair in common store).

Related

how to use netMsmqbinding - with server connected scenario

This might look a question where you can read the answer on MSDN, but I still want to ask about the scenario, as I want to solve the business problem.
I have a service hosted on a server, and a client makes service calls. It currently uses netTCP binding. Everything works fine when the service is available, when the server is up and running. Now, I need to handle the server down scenario. I use the local cache file on the client to serve the client requests in case of server down scenario. Now I want to cache all the requests made while server down and want to make service calls once server is up and running.
I am thinking about using the netMsmqBinding, because all I've read suggests that it works well in the disconnected scenario.
Q.1 Can I use the netMsmq to handle this scenario?
Q.2 If not then what could be another approach with which I can follow to solve this problem?
Q.3 Can I use WS-Discovery in case of server down to find that the client calls won't be able to contact the service?
EDIT : The scenario is Client-Server. But i do need to give response on every call to the client. The client is also developed and maintained by me only so i am in a good position to implement the best suitable solution.
Please guide me as I'm not too good with WCF.
Yes, you can use netMsmqBinding for this purpose. We are doing that for services running over a satellite link that can be down often.
One important limitation you need to take into account is that all calls must be one way, being a queue-based transport. If you need to get the results of a request, you'll have to provide a separate response mechanism (it can be a similar queue in the opposite direction)
Ad question 1: using MSMQ is excellent for a scenario where the service may not always be up and running. Note that the server that hosts the message queue must be up and reachable to receive the messages. However, you haven't told us anything else about your scenario, particularly why you currently have NetTCP. The reason that's important, is because there are some things you can not do with MSMQ, for example duplex communication won't work out of the box.
Ad question 2: an alternative may be to implement logic in the client (it's unclear from the question if you're the owner of the client software) to have a local queue and retry messages later if a service is (temporarily) offline. I guess you may even have a proxy MSMQ service on the client, relaying the messages to the main service once it's up.
Ad question 3: yes, you can use Discovery for this. The service will have to announce to the clients when it goes online or offline. The simplest example is using the UdpAnnouncementEndpoint. In the clients you can use the AnnouncementService class to listen to the service coming online or offline, and keep a local list of available services. Alternatively (for example when UDP broadcasts aren't feasible) you can create a discovery proxy service at a well known location that listens to announcements, which the clients can access for instant-knowledge on whether the service they need is online

prevent cross domain requests to my wcf services

I use wcf ui services communicate between my javacsript (jquery) and server side code. I find this work effectively.
However I want to make it more secure. I can I set up wcf so that the requests to the services can only be made from within the same domain, to prevent external clients from making such requests to my services.
So for example, my service opertion url is http://www.website.com/Service.svc/GetProducts. I want to set up wcf so that only requests from pages in the http://www.website.com are allowed. I presume this is in the realm of cross domain wcf requests but need some assistance in setting this up. Help would be great.
This simply isn't possible if your services are exposed to the web.
If something about your services isn't secure enough for that, you should look into fixing that problem - not trying to prevent people from making requests.
Anyone can always use a debugging proxy like Fiddler, Charles, etc. or a tool like WireShark to send any data they want to your services - including a complete replay of a request made via the browser. (Including referrer http headers, etc).
If your situation allows for it, perhaps you might consider using a VPN appliance or something similar, and restrict access to users inside your network (or coming in through the VPN). That way there is less concern about your security of the services.... however it's a known fact that "internal attackers" are just as prevalent, if not more so, than external ones... so don't get too comfy.
Let me head this argument off at the pass too, while I'm at it; someone might suggest that browsers already prevent cross site scripting like that. Yes, that's true. But usually it would be the developer of the other application adding the client side script to call those services - and he/she could just as easily make that request on the server side and proxy the results along to the client.

Customer Support via Web Service - how to secure the Web Service?

My customers can ask questions directly in my (windows forms) app. The app talks to a web service which stores the messages in a db on my server. Problem: A competitor decides to spam my Web Service. What can I do to prevent this and is there a cryptographically save way of doing this?
The things I came up with until now are:
Hide the WSDL information so an attacker does not know the Web Service interface. Analysing my code or sniffing the traffic will reveal this information quickly however.
Create a token which I sign with a public key stored in my app. The Web Service can test this way if the message has been sent by my app. Well in theory at least. Again an attacker could rip the public key out of my app and create valid messages himself.
So I'm pretty stuck here. Is there any way to do this right and prevent dos attacks on my web service or is a web service the wrong way to do this in general?
Thank y'all.
You're right- putting a private key in your app won't slow anyone down much, no matter how hard you obfuscate it. Nor is obscurity on your WS metadata.
Probably the best way (if you can't do authentication) would be to throttle by IP (one comment per X interval). Just keep an in-memory dictionary of client IPs and the last time you saw a comment from there, and reject requests quickly if they happen too soon. That'd at least require a big DDOS to cause major problems. Reap the dictionary for old entries every hour or so to keep it from growing without bound.
#nitzmahone is right. Just to add to this: This is no different from someone spamming a web-based form. If you're really worried about this, you can do what web forms do (e.g. server sends token and CAPTCHA image, user decodes the CAPTCHA, client app sends token, decoded CAPTCHA and the actual request).
Just like in web apps, you can turn this functionality on only if traffic from some IP exceeds a certain threshold.

Is it possible to enforce web service calls from known client only?

Scenario:
A publically available Web Service that I have full control over.
But I only want this specific desktop application (my published application) to have access to the Web Service.
I could store a secret password in the desktop client, but that would be easy to crack.
Is there any known implementation that enforces this?
PKI, assymmetric keys?
If the public will have access to copies of this Desktop App, any good reverser will be able to crack it and "imitate" its transactions with the server. It doens't matter how secure is your cryptography, everything you app needs to encrypt/decrypt data is included in the binaries, so the cracker only needs to dig it out of it.
The objective of cryptography is to protect data while it is being transfered, from "middle-man" hackers, but if you have access to anyone of the peers, you can easily crack it.
Your server must never trust what comes from the client side.
[edit resuming]
Despite you cannot 100% guarantee a supposed client to your server is or isn't your App or some "emulator" made by thirdies, you can complicate things to them. Its a common practice in game anti-cheats to sometimes, randomly, make the client App a trick question like "whats the hash of your main.exe from offset A to offset B?" or "from now on packet type 0x07 swaps with packet type 0x5f". Once a fake is detected, server enter in a "silly mode", act malfunctional, and blacklist their IP/account to this mode for several hours so they cannot have sure of what their program is doing wrong.
If you detect someone is building an emulator, make them start all over again: jumble the packet type tables, cryptography tables, change some packet formats and force your clients to update. You won't see crackers bothering you for a while... LOL
WS-Security provides for X509 encryption.
Part of that implementation includes the possibility of only giving specific clients the generated public key. That way, only your selected clients can connect to the service.
The easiest way is message security using client and server certificates. The best way is to import the client certs in your server machines and hard code the client cert thumbprint in the app.config file. The other way is negotiation of certs which I haven't tried before.
If you are using IIS to host the service then client certificates using SSL is another option.
MSDN link on WCF Security.

How to store WCF sessions so another application can access them

Hi I have an application that operations like this..
Client <----> Server <----> Monitor Web Site
WCF is used for the communication and each client has its own session on the server. This is so callbacks can be used from the server to callback to the client.
The objective is that a user on the "Monitor Website" can do the following:
a) Look at all of the users currently online - that is using the client application.
b) Select a client and then perform an action on the client.
This is a training system so the idea being the instructor using a web terminal can select his or her target client and then make the client application do something. Or maybe they want to send a message to the client that will be displayed on the clients screen.
What I cant seem to do is to store a list of all the clients in the server application, that can then be retrieved by the server. If I could do this I could then access the callback object for the client and call the appropriate method.
A method on the monitoring website would look something like this...
Service.SendMessage(userhashcode, message)
The service would then somehow look up the callback that matches the hashcode and then do something like this
callback.SendMessage(message)
So far I have tried without look to serialise the callbacks into a centralised DB. However, it doesnt seem possible on the service to serialise a remote object as the callback exists from the client.
Additionally I thought I could create a global hash table in my service but im not sure on how to do this and to make it accesible application wide.
Any help would be appreciated.
Typically, WCF services are "per-call" only, e.g. each caller gets a fresh instance of the service class, it handles the request, formats the response, send it back and then gets disposed. So typically, you don't have anything "session-like" hanging around in memory.
What you do have is not the service classes themselves, but the service host - the class that acts as the host for your service classes. This is either IIS (in that case you just need to monitor IIS), or then it's a custom app (Windows NT Service, console app) that has a ServiceHost instance up and running.
I am not aware what kind of hooks there might be to connect to and "look inside" the service host - but that's what you're really looking for, I guess.
WCF services can also be configured to be session-ful, and keep a session up and running with a service class - but again: you need to have that turned on explicitly. Even then, I'm not really sure if you have many API hooks to get "inside" the service host and have a look around the current sesssions.
Question is: do you really need to? WCF exposes a gazillion of performance counters, so you can monitor and record just about anything that goes on in WCF - wouldn't that be good enough for you?
Right now, WCF services aren't really hosted in a particularly well-designed system - this should become better with the so-called "Dublin" server-addon, which is designed to host WCF services and WF workflows and give admins a great experience monitoring and managing them. "Dublin" is scheduled to be launched shortly after .NET 4.0 becomes available (which Microsoft has promised will be before the end of calendar year 2009).
Marc
What I have done is as follows...
Created a static instance in my service that keeps a dictionary of callbacks keyed by the hashcode of each WCF connection.
When a session is created it publishes itself to a DB table which contains the hash code and additional connection information.
When a user is using the monitor web application, it can get a list of connected clients from the DB and get the hashcode for that client.
If the monitor application user wants to send a command to the client the following happens..
The hashcode for the sessionn is obtained from the db.
A method is called on the service e.g. SendTextMessage(int hashcode, string message).
This method now looks up the callback to the client from the dictionary of callbacks and obtains a reference to it.
The appropriate method in this case SendTextMessage(message) is called on the callback.
Ive tested this and it works ok, Ive also added a functionality to keep the DB table synchronised to the actual WCF sessions and to clean up as required.

Categories