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

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.

Related

Need help in protecting WCF service

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).

C# Know if server is being accessed from application

I have recently created an API on my server in PHP, but I have discovered that I shouldn't use my API directly with an API key because sensitive information like that can't be held securly inside an EXE. I did some research and people recommend creating a proxy between the API and your application, but even still that can be broken into.
I was wondering, how can I make my server know if it is being accessed from my C# application, or from another source? The reason why I want to know is to stop potential hackers accessing my gateway and using it themselves.
Thanks
SSL with a login?
There is no way for you to be certain someone is using your application to access a web service. I'm in a similar boat, and the most you can do is ensure the communication channel is secure (SSL) and use a username/password or something similar. You also have to be aware that anything done on the client's computer can be compromised. So much so, that you should pretty much assume that your application will be open source to anyone that wants it.

Windows network authentication the right way

I am about to start on a project that will be running as a windows service listening for incoming connections and doing some things locally then sending a reply message. I understand the basic concepts with sockets and communicating over the network, however the things the service are doing could very easily abused. I would like to authenticate the person connecting, preferably against the windows local users on the machine the service is running, to see if they have windows administrative/power user rights.
I know how to do it check the rights once I have their information but I know sending the user name and password to the application over the network in the clear is a no no. I was thinking of just encrypting the password with some secret key but I know "trying to be clever" is the worst possible thing you can do in cryptography so I wanted to know what is the "correct" way to handle this situation.
My second idea was just create a shared self signed certificate between the client and the server and just use TLS for the entire connection.
I may as well post what I was thinking of doing, if it is the right thing to do say so in the comments.
Both the client and server will have a PSK at run-time the server will send a random number to the client. the client will encrypt the credentials with the PSK and the random number as the IV. It will send back the encrypted blob plus whatever commands it needs done.
I am not concerned about replay or mitm attacks. I just want to authenticate the user and not have peoples passwords blasted all over the network.
Scott,
this may be a bit overkill and a bit off topic, but have you considered using a web service interface to serve your clients (instead of using raw sockets)?
ASP .Net web service interfaces are easy to implement, and in the end, you'll end up with a very well defined interface. They also have support for authentication and secure communication.
ASP .Net Web Service Tutorial
HTTP Security and ASP.NET Web Services

Server/Client Verification?

We're considering creating a program which sends a POST request to a server-side program for some processing. We'd like to consider some sort of verification to make sure the POST request isn't a random spammer attempting to overwhelm our system or something. I don't know too much about this stuff, but I was thinking the client might send a date-num and an "encrypted" date-num (not securely encrypted, just using some special algorithm). The server would then both encrypt the date-num AND decrypt the client-encrypted date-num. If either the encrypted date-nums or the decrypted date-nums didn't match, obviously it wasn't a request from our client, so the server will not act on the request.
As I said, I don't know that much about this. Am I going about it the right way? Is there a better way? If this is an ok way, whereabouts might I go looking for "encryption" algorithms? (most of the algorithms I find are for secure-encryption and can only be decrypted on the same machine. I don't care that much about security--I just am looking for verification).
Thanks a bunch for your help.
PS I'm not sure if this is a duplicate, because I didn't really know what to search. I couldn't find any other questions about this, but that doesn't mean anything.
EDIT:
To clarify, the server code should be as "drop-in" as possible -- e.g. if it can be done using straight PHP or ASP.NET rather than mucking around with server configurations, then that would be better. Same on the client end. Keep in mind this does not have to be secure, we're just attempting to keep spammers from POSTing random data a million times.
You could use ssl and client certificates and let the webserver handle it transparently. This way both the server and the client can be (more or less) sure about whom they are talking to.
What will your webserver be? IIS, Apache, ... ?
If it's an apache take a look at httpd 2.2 docs, Client Authentication and Access Control.
If it's an IIS see Enabling Client Certificates in IIS 6.0 (IIS 6.0)
Try using a cryptographic nonce.
On the page from which the POST is launched, a random number is generated and stored in the database with the requesting IP address and an expiry time (15-30 minutes?).
The same random number is stored as a POST variable.
On POST, in order for the processing to occur, there must be a successful lookup matching the nonce and IP address before the expiry time.
Combined with a honeypot captcha, it should do a good job of preventing bots from straining your system.
The usual approach for a problem like this is the inclusion of an HMAC. It allows integrity checking and sender authentication by the use of a secret key.

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.

Categories