32

Our application has recently gone through penetration testing. The test found one critical security breach, which is essentially:

The problem:

  • Attacker sets up a WiFi spot.
  • User enters our site (which is HTTPS).
  • Using a tool like Cain, the attacker either redirects the user to HTTP, or keeps them in HTTPS with a spoofed certificate. (Either way, the user had to go through the "get me out of here"/"add exception" page)
  • User enters her user name and password.
  • The password is posted to the MITM attacker, who can see it. Apparently Cain has a feature to automatically harvest user name and passwords, and our password would be easily caught there.

Suggested solution

The report recommends encrypting or hashing the password in the client side (using JavaScript), in a way that cannot be replayed (e.g. using one-time pad / time stamp). They could not recommend a specific schema (they did mention client certificates, which might be unpractical for a large application).

Is is worthwhile encrypting or hashing the password before posting it? It is common practice?

Kobi
  • 655
  • 7
  • 17
  • 5
    I tried to keep my opinion out of the question. If the goal is to keep the password hidden, it seems futile. The attacker here, assuming the user authorized the certificate, can do anything. The attacker can inject HTML and implement a full key logger, for example, or inject ads, or even "download a trojen" link. We would only solve a narrow problem of mindless harvesting. I don't want to implement something even *I* can easily get around... However, if we're talking about hashing, I can get behind "server never knows the real password" policy. This is neat. – Kobi Aug 31 '14 at 08:52
  • **Small rant**: The title of the section is "Exposure to Man-in-the-Middle Attack". This suggest that somehow we can fix it. In fact, it should have been "After user authorizes a cerificate, MITM attacker can get the password by sniffing". Our management now think that we have a MITM vulnerability, and that I oppose fixing it. Also, saying "Login Credentials [..] are passed over the network in Clear Text" is just cheap. – Kobi Aug 31 '14 at 08:57
  • 6
    IMHO whoever wrote this report should have known what @Steffen Ullrich mentioned in his answer - the recommendations in the report lead to much higher risk vulnerabilities than the current situation (which is the accepted way all over the web) What I am trying to say is that they don't seem professional to me. – aviv Aug 31 '14 at 12:26
  • 2
    SSLstrip can actually be [partially mitigated](http://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security) (also get into the [whitelist](http://www.chromium.org/sts), [more here](http://security.stackexchange.com/questions/64979/mitigating-sslstrip-by-only-serving-a-site-over-https/64987#64987)), but the suggestions from the report are just senseless and don't help anything. – user10008 Aug 31 '14 at 16:07
  • 7
    This is a rare case in which I would hazard a guess as to the identity of the pentesters, and obvious incompetence aside, I would point out (if it is indeed the company I believe it to be) that they have a vested interest in this misguided thinking, having just spun off a startup company to build and sell such counter-productive products. As @aviv mentioned, their recommendations are worse than the "problem" they purport to solve - in fact I'd run across their product that does just that, at a client engagement... I didn't know it was a commercial product, I called it out as a vulnerability. – AviD Aug 31 '14 at 18:43
  • @AviD - In their defense, they did not recommend any product, but they did point us to a site that "got it right". They do not post the password but encrypts/hashes it first. That is after I pointed that major US banks, Google, and PayPal just POST it. I *think* the product is called "strong authentication", but it might be just a buzzword. – Kobi Aug 31 '14 at 19:03
  • 1
    Just remember clearly: In this MITM-Scenario, the Attacker has absolute control over the whole Client-Traffic! The Client will not even connect to your site AT ALL! So whatever you do on your page, whatever tricks and features, won't even reach the client, since the Attacker can send him whatever he wants. He can just strip out any JS, grab the password and then redirect to your original site. – Falco Sep 02 '14 at 11:25

3 Answers3

51

This recommendation makes no sense: The JavaScript code used to hash or encrypt the password has to be transferred to the client too. If the attacker is able to mount a man-in-the-middle attack he will be able to inspect the JavaScript code used for encryption too or might even replace it with something else (like no encryption).

Hashing instead of encryption makes even less sense, because this would only work if the server accepts the hashed password instead of the real password. In this case the attacker would not even need to know the password, he only needs to know the hash.

What might help would be client certificates because you cannot mount an SSL man-in-the-middle attack which preserves the client certificate (and a downgrade to plain HTTP would not send the certificate either). But, because you have to distribute the certificates to the clients first and make them install it inside the browser, this solution works only when you have few clients.

Apart from that: if the attacker is in the middle he might not need the password at all. All he needs is that the victim has logged in and then the attacker can take over the existing session.

It might also be useful to detect such a man-in-the-middle situation, so that you can inform the user and deny login from compromised networks. Some ideas to detect connection downgrades (that is http to attacker which than forwards it as https):

  • Check the method of the current location with JavaScript.
  • Create a secure cookie with JavaScript. It should only be send back if the site is served with https (that is no downgrade).
  • Include a script as HTTP which servers an image and check at the server side how the image was included. If it was included as HTTPS you can assume a HTTP downgrade attack because you've explicitly included it with HTTP. If it gets accessed with HTTP you have a downgrade attack too (but with a smarter attacker) or the browser does not care about mixed content.

And on how to detect man-in-the-middle with faked certificates:

  • Setup a second https site (with a different hostname) and construct an ajax request to this site in a way, which is not simple for the attacker to change to http (e.g. create URL dynamically). If the attacker just tries to MITM any site this ajax request will fail at least with some browsers, because the certificate is not trusted and the browser will only prompt the user for the primary certificates of a site.

Of course all of this only helps against an attacker which is not really determined to hack especially you, but just takes the easiest targets. In this case all you need to have to do is to be a bit harder to attack than the rest.

Steffen Ullrich
  • 184,332
  • 29
  • 363
  • 424
  • 2
    Right. The attacker can easily get the password or take over the session. But: (devil's advocate) The scenario is an attacker who is not too malicious or competent, and all he/she does is to harvest passwords "passively", and looking at them at the end of the day. As for hashing: it could work if we include a one-time/time-based token in the hash. – Kobi Aug 31 '14 at 09:02
  • 3
    Passive sniffing of SSL can only be done if the attacker knows the private key of the servers certificate (and RSA key exchange is used), so the attacker must make an active man-in-the-middle attack. And if you think that its all the attacker can do why not just XOR the password with some fixed string? This might keep script kiddies away if they just use existing tools they don't understand. But of course it does not help against a real attacker. – Steffen Ullrich Aug 31 '14 at 09:08
  • "Passive" was the wrong word here, sorry. Just to be clear: the scenario involves the user adding an exception and accepting the attacker's certificate, while the attacker impersonates the user against our server, so the attacker does not need the private key. I gave the exact XOR example to my manager, by the way! – Kobi Aug 31 '14 at 09:17
  • 7
    I think it is reasonable to say that HTTPS, correctly implemented, is a perfectly reasonable security control to defend against MiTM attacks. @Kobi, your pentester should have factored in the likelihood of such an attack being carried out successfully, which is significantly lower given that a user would need to approve/ignore an invalid certificate. At the very least, such an issue should be assigned a _low_ level of risk/severity (not _critical_). This could then be considered an acceptable level of risk if client certificates break business requirements. – itscooper Aug 31 '14 at 11:31
  • I've added some ideas on how to detect such a man-in-the-middle attack so that you could warn the user and stop the login before the user can enter their credentials. – Steffen Ullrich Sep 01 '14 at 02:33
  • Steffen - You've been a great help, thanks. A couple of questions regarding your edits: **1.** as for "Include a script as HTTP" - I'm not sure I get it. My site is HTTPS. If I have any part of it that is HTTP, **all** users will get a mixed-content warning. **2.** second https site - I don't think it matters how we construct the URL. At the end, the browser sends a request and the attacker sees that. Also, is it possible (even sensible) for the attacker to use the same (root?) certificate for all requests? – Kobi Sep 01 '14 at 05:12
  • @Kobi: 1. yes, all users get a mixed content warning which usually is only a change of the icon. So this could be done just at an initial page and then redirect from the there after you've determined if the user is affected. But doing the test with a https only cookie probably affects the user experience less. 2. constructing the URL is only done so that the attacker does not downgrade it to http with a simple search+replace of https with http over all content. – Steffen Ullrich Sep 01 '14 at 05:43
  • What if JavaScript is disabled? – the_drow Sep 08 '14 at 08:55
  • 1
    @the_drow: you can still include an img with src from another https domain to detect at the server side if the image gets loaded. But then you cannot distinguish between image loaded because of no MITM or because of sslstrip. Obfuscating the loading with JavaScript and thus excluding it from SSL-stripping helps to distinguish both cases. – Steffen Ullrich Sep 08 '14 at 09:15
  • These are all fair points. From my point of view, encrypting (or rather hashing) a password client side gives me, the acting sysadmin, a level of comfort. There is no chance that I will ever accidentally see a user's raw password. I don't want that responsibility! Other than that, I don't think there's a real security argument to be made about the need for js encryption. – afourney Dec 08 '15 at 03:15
  • @SteffenUllrich: Many browsers are configured to pass https:// through what are supposed to be secure proxies. I would think it far more likely that such a proxy might passively capture a log of data that's going through it, than that the proxy would tamper with Javscript code going to a client machine. – supercat Jan 17 '17 at 21:16
12

I would suggest implementing HTTP Strict Transport Security instead, which prevents the user from accepting the spoofed certificate in the first place.

suriv
  • 205
  • 1
  • 7
  • 1
    Thanks! That's a good point (which [user10008](http://security.stackexchange.com/questions/66475/for-an-https-web-application-is-it-worthwhile-to-encrypt-the-password-before-po#comment108350_66475) also mentioned), and seems to address this problem directly. I missed the fact it also disables accepting a self-signed certificate. I would point out that Strict Transport Security is [not supported by any version of IE](http://caniuse.com/#feat=stricttransportsecurity) (≤11), but would probably be on the next version (12). – Kobi Sep 02 '14 at 05:56
  • 1
    IE 11 added support [in an update](https://blogs.windows.com/msedgedev/2015/06/09/http-strict-transport-security-comes-to-internet-explorer-11-on-windows-8-1-and-windows-7/) on June 9, 2015. – suriv Jan 05 '17 at 01:17
3

If you want ignore that the attacker could easily replace the Javascript code during a active MITM attack:

You could generate some asymmetric encryption key, provide the client with that public key to use it to encrypt the password client side. If you use a new key for every login nobody should be able to replay the password.

flob
  • 131
  • 3
  • If the attacker has already set up an active MitM (with a SSL cert as per the question) then he/she would be able to intercept the public key anyway. – Chris Murray Sep 01 '14 at 12:34
  • Yes :-) And it won't be of any use without manipulation of the Javascript. He wouldn't be able to replay the password nor to decipher it. – flob Sep 01 '14 at 12:42