WCF in production and deployment - c#

I know that their are questions and articles about WCF deployment, but i don't find one that actually solves my issue.
So i have a WCF service that is going to be used over tcp. If i set the security to transport, then i am obligated to use for usercredentials certificate or Windows. I don't want to use a certificate but i can't be sure that the service will always be hosted in a windows domain. So it leaves me with certificate security. I know that i can create a certificate with makecert, but what must i do when i want to deploy the service onto a server? Do i only need a certificate for the service or also the client that connects needs one?
Also if use message security, i need to have a certificate for the service.
EDIT,
In intranet scenarios, is it ok to use self signed certificates?

I didn't know myself, was just looking here:
WCF easiest security mode to implement
one of the best comments I think, in regards do just checking user/pass on both sides of the wire:
Such solution will not be secure. You talking about symmetric encryption where all clients and server has to share same key. Once any client get compromissed (and key is stolen or shared with anybody else) the security is gone. User name and password has nothing to do with encryption. – Ladislav Mrnka
You may be able to do it, but it might overlook the bigger question: why choose this route in the first place?
Here's some code for plaintext passwords if you really want to go down that route....
http://webservices20.blogspot.com/2008/11/how-to-use-clear-usernamepassword-with.html

Related

WCF: Use credentials but don't encrypt anything?

We have an application which features different levels of users. This is not a "security feature", this is more to prevent that users change anything that is not related to their role.
Also, the server is not public and only available on local connection(network not accessible from internet).
We would like to use credentials, but we would like that no encryption and ssl is required(because the service has sometimes a lot of data to transfer and we don't want to "loose" time to encrypt/decrypt each time).
Is this possible? What should be used as Security Mode?(we do configure our services in the code, not through XAML).
Thanks
I would want to know more about the use case you are looking for.
But assuming that you are just trying to prevent anonymous access of an application, you may go for a windows authentication if you are using AD based workstations. If not then you may need to rely on custom authentication which just pops up a challenge before allowing you through.
EDIT: Based on your comment, I understand that you are using CustomUserNameValidator in WCF for auth. Understand that it is not a mandate to use certificate when you are using this. However, certificate improves the security. If you are absolutely sure that your network is protected and snoop-free, you can use self signed certificate using makecert. However, i will always advise to purchase a certificate.
A sample is found here https://blogs.msdn.microsoft.com/pedram/2007/10/05/wcf-authentication-custom-username-and-password-validator/
You can also choose to use HTTP custom binding with plain username / password without any certificate involved

Password is in clear text after imlementing SSL [duplicate]

I asked a question here a while back on how to hide my http request calls and make them more secure in my application. I did not want people to use fiddler 2 to see the call and set up an auto responder. Everyone told me to go SSL and calls will be hidden and information kept safe.
I bought and installed an SSL Certificate and got everything set up. I booted up fiddler 2 and ran a test application that connect to an https web service as well as connected to an https php script.
Fiddler 2 was able to not only detect both requests, but decrypt them as well! I was able to see all information going back and fourth, which brings me to my question.
What is the point of having SSL if it made zero difference to security. With or without SSL I can see all information going back and fourth and STILL set up an auto responder.
Is there something in .NET I am missing to better hide my calls going over SSL?
EDIT
I am adding a new part to this question due to some of the responses I have received. What if an app connects to a web service to login. The app sends the web service a username and a password. The web service then sends data back to the app saying good login data or bad. Even if going over SSL the person using fiddler 2 could just set up an auto responder and the application is then "cracked". I understand how it could be useful to see the data in debugging, but my question is what exactly should one do to make sure the SSL is connecting to the one it was requesting. Basically saying there cannot be a middle man.
This is covered here: http://www.fiddlerbook.com/fiddler/help/httpsdecryption.asp
Fiddler2 relies on a "man-in-the-middle" approach to HTTPS interception. To your web browser, Fiddler2 claims to be the secure web server, and to the web server, Fiddler2 mimics the web browser. In order to pretend to be the web server, Fiddler2 dynamically generates a HTTPS certificate.
Essentially, you manually trust whatever certificate Fiddler provides, the same will be true if you manually accept certificate from random person that does not match domain name.
EDIT:
There are ways to prevent Fiddler/man-in-the-middle attack - i.e. in custom application, using SSL, one can require particular certificates to be used for communication. In case of browsers, they have UI to notify user of certificate mismatch, but eventually allow such communication.
As a publicly available sample for explicit certificates, you can try to use Azure services (i.e. with PowerShell tools for Azure) and sniff traffic with Fiddler. It fails due to explicit cert requirement.
You could set up your web-service to require a Client-side certification for SSL authentication, as well as the server side. This way Fiddler wouldn't be able to connect to your service. Only your application, which has the required certificate would be able to connect.
Of course, then you have the problem of how to protect the certificate within the app, but you've got that problem now with your username & password, anyway. Someone who really wants to crack your app could have a go with Reflector, or even do a memory search for the private key associated with the client-side cert.
There's no real way to make this 100% bullet proof. It's the same problem the movie industry has with securing DVD content. If you've got software capable of decrypting the DVD and playing back the content, then someone can do a memory dump while that software is in action and find the decryption key.
The point of SSL/TLS in general is so that the occasional eavesdropper with Wireshark isn't able to see your payloads. Fiddler/Burp means that you interacted with the system. Yes, it is a very simple interaction, but it does require (one) of the systems to be compromised.
If you want to enhance the security by rendering these MITM programs useless at such a basic level, you would require client certificate authentication (2-way SSL) and pin both the server and client certificates (e.g. require that only the particular certificate is valid for the comms). You would also encrypt the payloads transferred on the wire with the public keys of each party, and ensure that the private keys only reside on the systems they belong to. This way even if one party (Bob) is compromised the attacker can only see what is sent to Bob, and not what Bob sent to Alice.
You would then take the encrypted payloads and sign the data with a verifiable certificate to ensure the data has not been tampered with (there is a lot of debate on whether to encrypt first or sign first, btw).
On top of that, you can hash the signature using several passes of something like sha2 to ensure the signature is 'as-sent' (although this is largely an obscure step).
This would get you about as far in the security way as achievable reasonably when you do not control (one) of the communicating systems.
As others mentioned, if an attacker controls the system, they control the RAM and can modify all method calls in memory.

Using WCF, how can I make sure only trusted assemblies call my service?

I have a simple service contract, defined as:
[ServiceContact]
public interface IEcho
{
[OperationContract]
void Hello(string value);
}
which is implemented in a local WCF service (accessed through a net.pipe:// address).
I need to know who is calling the service.
Basically, I need to reject the calls to IHello.Echo made from any assembly not signed by me, for security reasons. The Hello method should not be available to untrusted callers.
I vaguely remember that in the old .NET 1 remoting days, we could walk the stack and check the identity of the callers. But how can I do this with WCF?
You can't authenticate the caller assembly. Caller of the service resides in a different process that you have no access.
Instead you need to use any solution that provides client authentication in WCF. Since you are using named pipes, you should look into message level authentication (as opposed to transport level).
In WCF you can interrogate CLientCredentials object if you have authentication turned on.
You could also secure the service usign a certificate ... that way you know whoever is calling it has been issued the certificate ... that isn't the same as a signed assembly ... but it is the same as a certified caller from a known source.
You do that with the ServiceCredentials part of the web.config ... it is quite flexible in how you choos ethe certificate. If you wan tto lock down who can call the service i recommend this.
If you want to be in control of a list of people who can register and unregister than go for some kind of user storage and authentication . authorisation mechanism that calls off to a database.
response to comment:
Yeah fair enough. However in the situation with trusted assemblies the malicious user can simply copy the assembly. So i think you are strawmanning slightly tbh. One involves reverse enginnering the other requires xcopy.
Given your new requirement:
You need to write some kind of authenticator service that generates a pseudo random sequence has some kind of handshake using a revocable one time use certificate to sync up. There are several examples around ... you are getting into the territory of STS servers and authentication providers. In reality you probably want a window to resync over time and a pseudo random generator that can spit out the nth number in its sequence quickly. the algorithms exist but you are getting into the kind of realm where you need to be highly qualified to start giving advice without 3 pages of saying 'don't quote me this is hard shit'. I'd rather describe how to implement an encryption algorithm tbh - and i wouldn't do that either.
There is a saying with computers if you want a secure computer lock it in a safe, dump it in the ocean. It is logically impossible to be secure - you just have to determine the lengths you want an attacker to go through.
The fact is if you are in a trust situation you should know a lot of information from mac address to ip to certificate. you can revoke those credentials at any time and reestablish them. But if someone presents the correct credentials then to say they are not who they say they are is the same as saying a chair is not a chair - its being paranoid. the trick is to gather the evidence to make the decision.
If you want bullet proof authentication go out and buy it - it will cost you a lot of money
I've come across other questions along the same lines:
How do I securely authenticate the calling assembly of a WCF service method?
How to authenticate client application for trust of messages sent from it
and apparently, there is no secure way of making sure the sender of the message is indeed a specific strongly signed assembly. There is always some way a malicious assembly could spoof its identity.
In short, the answer is: it is impossible.

Can I avoid storing MS Exchange credentials while still being able to authenticate (against EWS)?

I'm building an application that syncs data between users' Exchange Server accounts (version 2007-2013 supported) and the application.
The application can't use impersonation (at least not in the typical case) as users could be on any number of domains and exchange servers.
I know I'm going to have to ask for their username/email-address and password initially. However, I really don't want to be responsible for storing these credentials if I don't have to (even if they are encrypted, I'd rather not).
I'm not sure what questions to ask, so I'm going with these:
How does Exchange Server authenticate? Do the user's credentials get sent directly to the server as they are, or are the hashed together before being sent across the wire? If they are hashed, how can I get/generate this hash for re-use on successive authentications?
Does Exchange Server send some sort of authentication token that can be re-used later (and forever, until password change or invalidation)?
If you know of a solution to the problem, that the answers to these questions won't address, please do provide it instead.
Active directory federation services is exactly for such tasks. You can read about it there.
As mentioned by Kirill, ADFS 2.0 is one of the best solution for your task. You can also look into other SSO implementations as well. Though the main goal of SSO implementation is to maintain single Login state for multiple application (thereby reducing multiple Login prompt for each application), some of your application goals seems relevant. Please do a thorough research on all the tradeoffs before heading to the sso implementation since there is a small degree of complexity involved during implementation. SSO suits best if you are considering integration of multiple application in the future with the exchange server.
To answer some of your questions (in the same order - considering an SSO scenario with ADFS 2.0):
The authentication to exchange server will be done via ADFS 2.0 (Which provides security tokens (STS service) - to your application after authenticating with AD/ main Directory service). All the communication is encrypted and token signing certificates are used for Integrity and confidentiality.
The lifetime of Security tokens sent by ADFS 2.0 can be configured and reused as required. Please see this blog post for more details.
Also you can configure the ADFS 2.0 (Federation Service) to send only the relevant claim values (like username and email address) to the application, thereby improving the data security.
The System.Net.CredentialCache should work to suite your needs. The WebCredentials is a wrapper for the System.Net.NetworkCredential. Depending on the connection type/domain ect you should be able to utilize System.Net.CredentialCache.DefaultNetworkCredentials or System.Net.CredentialCache.DefaultCredentials
perhaps you should take a look at this Links Connecting to EWS by using the EWS Managed API , Connect to Exchange - Getting Started Tutorial? hopfully it will give you a new idea how to solve your problem :)
because if i understand the information correctly you maybe over think problem but i haven't any experiences so i could also absolute wrong
Bottom Line
If you can't configure anything on the server, there's no automatically generated token to use. It's unfortunate, but you're facing the same general problem that web browsers have--saving the password.
It's worth noting that any authentication needs to be over SSL (an https connection) to prevent a third party listening in on the authentication.
Password storage thoughts:
My suggestion is then to be somewhat creative when storing the password. You can use a keyed encryption algorithm, and then use a hash to generate the key, letting you arbitrarily choose what goes into the key. You would want at least 3 pieces of information going into this: something unique to the device, something unique to the app, and something unique to the exchange server.
For example:
a unique id given by the device (it doesn't matter whether or not this value is app-specific or not, merely that it is consistent)
a (long) string of information compiled into the app, possibly keyed to installation specific values, say the time when the app was first used
something unique to the destination, like the DNS name and perhaps some more specific server info
If you're willing to provide the option to the user, you could have an authorization PIN of some kind that would also be added to the data.
All this data gets put together in one byte array and hashed. The hash (or part of it, or it twice, depending on the hash size vs. the key length) is then used as the key for the encryption of the password.
You could also include some check information along with the password to be able to check client side whether or not the password was decrypted correctly. (If the wrong data is hashed, the wrong key is generated, and the wrong result comes from the decryption).
It's worth noting that all the information to be used for putting into the hash needs to be stored on the device, which is why I would suggest a Pin to authorize the usage of the account.

WCF Authentication / WCF REST Authetication..Different Method?

I have made a WCF REST service which consumes data from an OLAP database and it is not Microsoft technology, ultimately, I would like to connect many other OLAP database to a single platform.
And after a lot of reading, the security for WCF REST is very discouraging, in summary, I have 2 choices, one is to use the Basic Authentication which expose username and password over the wire, or maybe a bit better, using Basic Authentication with SSL, now I need to get different certificates from the webserver. Or using Digest Authentication, which use an encrypted password and authenticate against the database, that's the best option, but in my case, it is not possible as I am not using Microsoft technology, the security is on different platform and I cannot encrypt my password using MD5 because the database cannot read the encrypted password.
That concludes me only be able to use Basic Authentication with SSL, but is this the correct way of doing? I see many products out there doing something similar to what I do, when they login, I do not see https, but only http, are they not secure and easy to hack?
I am not trying to make a bullet proof website, but a simple website, using Basic Authentication is too simple, or in fact it's almost like giving away the password, but using https, is that overkill?
So, after REST being that discouraging, let's not use REST, use the normal WCF, from what I have read, they shares the same problem.
Please give me some guidance. I think I have lost.
Many Thanks
PlayKid
Often, basic authentication is used for regular websites and yes, the username and password often go over the line readable if used with http. Https is already better, because the information is send encrypted over the line. But in practice, you only see this in place for commercial or banking applications. You cannot use MD5, which is a pitty, because that would be sort of middle-of-the-road approach.
So, depending on the application you will expose, use http for simplicity or https with a bit more complexity and safety.
By the way, big safety problems often have to do with SQL injection or a hacker being able to get some admin level privileges on your site. That way they get acess to a lot of info, while sniffing your line and getting a single user password combination is relatively harmless, if you take the needed precautions and counter measures.
Basically, Basic authentication with SSL is really very secure and shoul be used if its going to be exposed to outside world.
One easiest hack approach I have seen before and if you just want to authenticate (not authorize a endpoint) clients which are known set of clients use:
OperationContext.Current.ServiceSecurityContext.WindowsIdentity.Name
This will provide username accessing the service, Authenticate this usern with your DB or AD using LDAP if a valid user is accessing the service and with every request add a encrypted key that user needs to send as part of request. This way you know the username and encrypted key from the request.
You can also use this along with Basic authentication to be sure its not insecure.

Categories