Ensuring Secure HTTPs Connection - c#

Well i am implementing a Account Login system in my application in which i want to make sure that all the connections are secure so the user can't simply redirect the client connection to a mimicked server and gain access to the app without my permission. So here is the procedure i am imagining.
1- The HttpClient Connects to my SSL page.
2- Makes sure that the connection is secure (maybe by checking the certificate or something).
3- If the connection is secure it sends out the login credentials.
4- It receives the answer and if the account is valid it goes on, if not it terminated the connection.
So as you see my plane is very simple and i think it will be good to prevent some abusers or hacker from gaining access to my app without my permission and it relays on the powerful SSL certificate system; However, i don't know how could i implement this in real code so i really need your help illustrating how could i make sure that the HttpClient has connected to my real server using SSL and not anyone's fake server.

Here is all you need - SSL certificate validity/match to domain name is checked by default.
var c = new System.Net.Http.HttpClient();
Console.Write(c.GetStringAsync("https://www.facebook.com/").Result);

Related

How to protect a webservice in .NET from outer world except a single application?

I have a website with architecture (HTML + JSON + webservice (C#)) installed on a server which is open to internet. Now, my webservices are opened to the whole world so anyone can access it and may try to malfunction.
What I would like to do is to make my webservice to work limitedly to my application only instead of other applications. Like when a website is on open internet but its web services are private to the website only and not to the whole internet.
Right now there's a big data security concern.
The primary way would be to add some sort off login/account system. That then of course needs to be managed and all that.
The other posters' approaches of just putting some key or certificate into it will only work if it is not that important. Anything you store in the application is invariably reverse-engineerable. So if someone is decently determined, that level of protection is easy enough to overcome.
If the number of possible consumers is small enough, another approach might work:
Make it only reachable from the local network (IP adress ranges associated with Local Networks). Then use a approach like VPN so clients can connect to you local Network. Basically you move the account part to another System. But such a approach can have security issues, especially if that VPN connection goes straight into your DMZ.
In the end it really depends how critical that is. Security exists in flavors from "anybody reading his computers network traffic with Wireshark can break it" to "reasonably secure for high grade private data". We have no idea what level of security you need and what level of skill you have, so we can not give a useful answer just yet.
I would suggest you look into using Certificates to encrypt your webservice, then your application will call it using that same loaded certificate. Only an entity with your server certificate key will be able to decrypt your calls.
Accessing a web service and a HTTP interface using certificate authentication
Calling a rest api with username and password - how to
Edit: If you cannot use the certificate method because you are calling from say the browser directly, you might want to look at an authorization cookie of some sort, So that lets say on your login pages the request might be open to public but on all subsequent request you require authentication and once the user has logged in you rely on the authorization cookie or token to validate whether they have access.
Another method: IdentityServer for instance has provider token stores, so you can request a token from the store, then only with the issued token you can access the API. And your API would also then query the store to check the token is valid.
I found a very easy solution to it.. by getting ip address of the remote client's in web service i can validate whether the request is coming from my webserver or not
so anytime if any spamming client try to request my web service i will retrieve its ip on every request inside webservice and reject the request for ex :
if (HttpContext.Current.Request.UserHostAddress.ToString() == "127.0.0.1")
{
return "my server";
}
else
{
return "invalid client or spammer"
}

Managing Active Directory securely from another computer

I have created an ASP.NET website that has to access Active Directory on another server and change users passwords. The problem is that I need to authenticate with existing AD account and I cannot send AD user's password in plaintext when communicating with the Active Directory server. How do I communicate with AD server from ASP.NET website, so that connection is secure? My AD server supports LDAP protocol, but I do not know how to enforce communication with LDAP via a secure channel.
ASP.NET Website --------------LDAP/another protocol (secure)------------> AD Server
Fairly simple, you need to do two things :
Configure your Active Directory instance to accept connections over LDAPS, or port 636. You'll need a certificate (it can be self-signed) to set that up.
Update your LDAP authorization code to use this the new connection. This shouldn't be anything more than changing the server to "ldaps://{{IP OR DNS}}", and ensuring you're setting SessionOptions.SecureSocketLayer = true;
If you want to verify that it's working properly, Wireshark the traffic leaving your ASP.Net site that's going over port 636, and you should notice it's now heavily encrypted, and impossible to discern anything meaningful from.
I've done a ton of this stuff over the years, so I've had a few other questions surrounding this that should also help you out :
Set callback for System.DirectoryServices.DirectoryEntry to handle self-signed SSL certificate?
(This contains a full implementation of LDAPS)
Custom Multi-factor Active Directory Authentication
(This is a much more simple example, but would work perfectly fine for your purposes)

What is point of SSL if fiddler 2 can decrypt all calls over HTTPS?

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.

Implement Pass-Through Authentication in C#

I am developing a TcpClient/TcpListener based client-server application.
Now I have come to the point where I need to authenticate the user. I could use the PrincipalContext-Class on the server side and request username/password/domain from the client, but I don't want to send the credentials over the network. Additionally, I don't want to ask the user for their credentials again.
So, I know the Citrix Receiver which supports pass-through authentication. It uses the current logged on user and does not request any credentials and authenticates the user against the server. It just works.
How can I do this in my application? I thought about some kind of token which can be sent to the server, but I could not find any solution.
Wrap the NetworkStream in a NegotiateStream, and call the appropriate NegotiateAs... methods on both client and server.
The client can specify what impersonation level to allow, and the server can specify what level it requires (minimally Identification in order to determine client identity, but if you need to access local or network resources as the client, you could also specify Impersonation or, with the right network configuration, Delegation).
Once authenticated, the server can determine the client's identity and/or impersonate using the NegotiateStream's RemoteIdentity property.
As I mentioned in my comment, I don't know how Citrix affects this setup (never having used it), but if it's basically completely transparent to the application and everything uses standard Windows credentials, then this should work.
The .net Framework does have functions for Diffie-Hellman Key Exchange:
http://de.wikipedia.org/wiki/Diffie-Hellman-Schl%C3%BCsselaustausch
http://www.codeproject.com/Articles/24632/Shared-Key-Generation-using-Diffie-Hellman
If you are writing both the client and the server parts of the application, then you can encrypt the user's credentials for passing across the network and decrypt at the other end.
Working on the assumption that on the client machine, a malicious user could extract the encryption key from your application (using strings or similar) then symmetric encryption is not suitable. Therefore asymmetric (public-private) encryption seems suitable. Generate a pair of keys and the server's key should remain private (and only on the server) and the clients' key can be included in the application on the client machines. Then it doesn't matter if the key is extracted from the app as credentials can only be decrypted with the secret and secure private key on the server. This class has done most of the ground work for you.

How to prevent someone from overriding the code that grabs the windows authentication and uses the username to make wcf calls?

Basically, if you use WindowsAuthentication to grab the username, store in a variable and then pass that to any services you use, what's to stop someone from hacking your code and passing in another username?
On the client end you can check the IsAuthenticated, but then after that it only lets you grab the Windows Username, not the Windows password.
Is there some way to just pass that authentication object itself without letting it be hacked? Otherwise, I might have to switch back to not using Windows Authentication as my Authentication and custom rolling a user/pass with a db table.
You can't pass user's credentials outside of your server due to "NTLM one hop" behavior. You may be able to configure Kerberos authentication to handle cases when you need user's credentials flow between front end and backend servers.
The other option is to establish trust between servers (i.e. HTTPS with client certificate) so backend server is able to trust user name coming from your server (as it would be the only one with correct client certificate). You will not be able to impersonate the user on backend server as you will on ly have a name.

Categories

Resources