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?

  • 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 8:52
  • 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 (also get into the whitelist, more here), 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
  • 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 2 '14 at 11:25

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.

  • 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 9: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. Aug 31 '14 at 9: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 9: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
  • 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. Sep 8 '14 at 9:15

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

  • 1
    Thanks! That's a good point (which user10008 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 (≤11), but would probably be on the next version (12).
    – Kobi
    Sep 2 '14 at 5:56
  • 1
    IE 11 added support in an update on June 9, 2015.
    – suriv
    Jan 5 '17 at 1:17

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.

  • 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. Sep 1 '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 1 '14 at 12:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.