is it possible to connect to SSL via a web client so that it can not be decrypted later by programs like Charles or Fiddler?
My Problem is, I have a Application white a Login, if the Password and Username from a User is correct, the Server returns Success. But if the user reads the response, he can easily fake it white Charles and „bypass“ my Login.
That depends on what you are trying to do, and why. Fiddler decrypts traffic by installing a root certificate on your computer, and then uses that basically make a man in the middle attack. Or in other words, with the users permission it subverts the security model of windows. So if you rely on windows to validate the SSL certificate used, there is nothing you can do about it.
If you only have one server that you really want toconnect to, you can validate that the certificate you are getting is the one and only one that you do indeed trust. This is known as certificate pinning.
If you are worried about someone storing the traffic and later using Fiddler to decrypt it, you can stop worrying.
Related
I understand that this is not a good practice.
I use fiddler, and I usually see the password in plain text even in https. I would like to have the client quickly obfuscate the password before sending it out. When the server receives the request, it should be able to deobfuscate it.
Normally what I see in fiddler post to server
{
"secure_username": "mmatiasn",
"secure_password": "chickennuggetboy" //Plain text password I hate to see...
}
What I would like to see being posted to server
{
"secure_username": "mmatiasn",
"secure_password": "d162314" //Obfuscate password that the server can deobfuscate.
}
I'm working on a small project to learn more about dotnet and it's currently only accessible over a small intranet network I own. I don't want to set up https as well.
You don't, just use https which is the standard (for a reason).
There is no need to do this, if there was then that would be the standard practice.
To hash the password you need the salt which should not leave the server (the hash shouldn't either but you don't need it to create a new hash).
Use https and send the password in the message body of the request (use POST or maybe PUT). Yes, you can see the content if you are the client or with fiddler in between if its your PC, that is by design. If you are outside of the client using a sniffer or something to intercept traffic then you cannot see the content as it is encrypted.
... only accessible over a small intranet network I own. I don't want to set up https as well.
Why? If its an intranet then use a self signed certificate (free) which is relatively simple to setup and takes almost no time and much less time (not to mention secure) than it would take to develop anything like what you are suggesting.
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.
I am wondering how is Google able to show messages like Cannot connect to the real mail.google.com or similar? Are the IP addresses of Google servers simply hard-coded within Chrome or is it possible to do a similar thing? This could help making sure clients are not visiting phishing or scams websites.
This errors only shows when trying to access Google related websites, nothing else.
Here is a sample of what Google Chrome shows when trying to connect to Gmail without providing the proxy credentials.
PS: I usually use C# & ASP.NET. I am open to suggestions.
EDIT :
Following the answer from SilverlightFox, is there any way to "request" the pinning of my website certificate? And/Or how to add it to the "STS preloaded list"?
As #Ted Bigham mentioned in comments, this will be achieved via Certificate pinning:-
One way to detect and block many kinds of MITM attacks is "certificate pinning", sometimes called "SSL pinning". A client that does certificate pinning adds an extra step to the normal TLS protocol or SSL protocol: After obtaining the server's certificate in the standard way, the client checks the server's certificate against trusted validation data. Typically the trusted validation data is bundled with the app, in the form of a trusted copy of that certificate, or a trusted hash or fingerprint of that certificate or the certificate's public key. For example, Chromium and Google Chrome include validation data for the *.google.com certificate that detected fraudulent certificates in 2011. In other systems the client hopes that the first time it obtains a server's certificate it is trustworthy and stores it; during later sessions with that server, the client checks the server's certificate against the stored certificate to guard against later MITM attacks.
From What is certificate pinning?:-
some newer browsers (Chrome, for example) will do a variation of cerficiate pinning using the HSTS mechanism. They preload a specific set of public key hashes into this the HSTS configuration, which limits the valid certificates to only those which indicate the specified public key.
HTTP Strict Transport Security (HSTS) is a technology that is implemented via a HTTP response header (sent via HTTPS only) that tells a browser to "remember" that a website is to only be accessed via HTTPS for a period of time. If HSTS is set on www.example.com and the user visits http://www.example.com before max-age has expired, the browser will request https://www.example.com instead and no request will be sent via plain HTTP. HSTS requires that the user has already visited the site in order to have received the header, however a workaround has been implemented by Google in their Chrome browser code:
Google Chrome and Mozilla Firefox address this limitation by implementing a "STS preloaded list", which is a list that contains known sites supporting HSTS. This list is distributed with the browser so that it uses HTTPS for the initial request to the listed sites as well.
Update following question edit
Following the answer from SilverlightFox, is there any way to "request" the pinning of my website certificate? And/Or how to add it to the "STS preloaded list"?
According to this blog post you should contact the browser developers to be included in the HSTS list and have your public key (or CA's) pinned in the browser:
is this domain HSTS-preloaded in Chrome? For now it is hardcoded in the binary and will hopefully grow. You can contact Chromium to have your site included in that list.
and
So right now, the only solution to pin public keys of CAs signing your website certificates would be to contact Chromium team to be included in the code.
The only way to fight the man-in-the-middle is to have some pre-shared knowledge. In this case those are hardcoded certificates of a couple of root authorities that your browser trusts. These root certificates are used by their authority to sign certificates of other authorities which in turn become trustworthy too. A chain of trust is built until you hit the certificate of mail.google.com.
When you go to mail.google.com you are automatically redirected to the HTTPS (note the S!) version of the site. HTTPS means certificates. Your browser downloads the certificate of that site and inspects if the signing chain is rooted by some of the authorities your browser trusts. If not: Big fat warning! Possibly man-in-the-middle spoof going on!
Another thing that might happen is that the redirect from HTTP to HTTPS fails because some firewall between you and Google blocks HTTPS. That might be the warning you are getting.
I'm building a .net app, and I'd like to make the web calls secure enough that its not easy to monitor the the traffic thru something like fiddler. I'd like to be able to know that the certificate from the server isn't as expected and then never send out a full request with the request data.
Twitter's iOS app does this. Someone I think would have to somehow make a copy of the twitter's https certificate and make that fiddler's certificate. I havn't done it myself, but i think that's how I understand it. What you see in fiddler is that the tunnel has been created, but no request was actually set out. Its same scenario when you don't have the fiddler's HTTPS certificate installed on the device and you open a browser to google.com / a tunnel is created and then the browser knows 'uhoh untrusted server' and displays a message to the user. I'd like to just make it more secure and only allow 1 certificate / my server's certificate.
Make sense? I think i figured out how to do it with making a separate full dummy request / but thats not ideal.
What you're asking is "How do I implement certificate pinning in my client application?"
The way to do that would be to attach a validation callback on the Service Point responsible for making your HTTPS requests. Your validation callback would override the default behavior ("Accept any certificate trusted by Windows") and would instead validate that the received certificate is EXACTLY the one you expect.
Now, before you go that route, keep in mind a few things:
An attacker with Admin or Debug privileges can easily change your code in memory to remove your validation. This is called the "Trusted client" problem.
Your validation will break if the code is ever run in a corporate environment where an security appliance is doing HTTPS inspection (e.g. BlueCoat, ISA TMG, etc)
Your validation will prevent "certificate agility" -- if the server cert needs to change, you will need to update the application. If you ever want to use a load-balanced configuration with multiple certificates, or a public HTTPS CDN, you would need to update your validation logic.
I am looking forward to have the less information as possible on my application resulting in pulling most of the data from a website or server and I would like to hear by advices and recommendations from everyone with experience in the field to help me improve my application.
Currently my authentication consists of:
To start the application the user have to input their username and password (without a valid user and pass the app does not work) and click login.
The credentials will be sent to my login page using HTTPS, the script only accept SSL connection and a personalized User-Agent name.
The login page will verify the credentials and send back a session and some initial data.
The session is reused to gather more data over time or as needed.
Side note: the SSL is 256 bits, the session auto expire after a few minutes
For the above basic authetication and data pulling would you recommend me anything else to implement ?
Should I change anything ?
2nd Layer of protection
Now I would like to implement more security by encrypting all the data sent from/to my application, my question:
What should I use to encrypt and decrypt the data, a pair of private and public keys held on both sides or RIJNDAEL's method ?
What is the proper way or what parts of information should I leave on the client and server or how should I form the knowledge of the common passwords or keys ?
For example if I was using a pair of RSA keys, I would need to leave 1 private key at the client and 1 public key since you cannot decrypt any data with the public key on c# while you can do it on the server and for Rijndael would need to have the IV and the key on both side.
What is the proper way to handle these ?
I will be very glad with practical reading material, comments, examples, suggestions, advices :)
UPDATE:
No one else wants to say anything ? I was hoping to get more input on this question and also tough that this was a fairly used method around ...
Sounds like you've considered the security of the app side of the equation at length. I'd suggest you turn your thinking to the website part of the equation.
When I look at security, I always look at two things:
Transport security--is your data protected while in transit? Sounds like it is, assuming you are using sufficient key length for the SSL cert on the server. Also, you can force the website do client cert validation as part of the SSL handshake. That ensures that no one can spoof the client app and convince your website to share information.
Payload security--should you encrypt the data payload? Is there a chance someone may be able to break into your web server, or better yet, via the DNS poisoning or some other method, convince your app to connect to a malicious server with a valid (for that cn), but different HTTPs certificate? Should you choose to encrypt the payload, you can piggy back the whole thing onto the same certificates you already use. Just make sure that the certs have data encryption bits turned on, and you can use private/public keys from the certs to encrypt the payload. So, if the malicious user replaced the cert, not only do they need to spoof the cn and the chain of trust, but also have the right public key from the app to decrypt the data you are encrypting with your private key and signing with server's public key.
Some other questions to ponder:
You are saying that the session is reused? Does it not expire? If not, you'd want to make it expire.
Can you leverage network security? Can you use a VPN tunnel or IP ACL to limit who can even gain access to the web server?
What about keyloggers? Passwords can be intercepted. The second authentication factor can be something a user has, like a key card or a fingerprint, or an RSA SecurId. If you don't want to go that far, you can present a user with a "site seal"-- an image that they have to recognize as associated with their account. Maybe even present several images and let them choose one that they've chosen during the signup process. You can also make them solve a small puzzle--something that will distinguish a human from a machine (CAPTCHA-type).
All these points minimize info stored on the client side--just a cert or two and a key to go with that cert.
The topic of security is vast, and we can start a whole discussion here on different implementation details. The above is just some points to think about.
Remember, that everything has cost. Security costs usability and CPU cycles. Proper balance is key, but that of course is up to you.
Before you build Fort Knox, make sure someone is going to want to live there :)