Stop doing client-side password hashing

Right, this has come up enough to write a post about it.

Stop hashing passwords on the client-side and sending the hash in the clear. It is not a substitute for HTTPS!

Here is an example of this being done on the DSC Security website. Go to “Security Professional Login”, and you get a pop-up login box. It looks like JavaScript is involved.

Note that the login page is served over HTTP (not HTTPS). This doesn’t always mean that the login credentials are passed over HTTP though. Sometimes the HTTP form submits to a HTTPS page.

This is still bad from a security perspective as the attacker can deliver you a malignant login form that submits credentials to a server under his control.

Regardless, DSC aren’t doing anything over HTTPS – it’s all HTTP – so it is all sent in the plain. HTTPS is essentially free these days – there is no excuse to not use it.

That said, it appears that someone at DSC has realised that HTTP a bad idea, so they have implemented… a thingy. A thingy that does little to improve security.

Here is the query that they send when I entered test/test:

GET /index.php?o=login&user=test&pwd=098f6bcd4621d373cade4e832627b4f6&remember=yes HTTP/1.1

So that parameter pwd isn’t test. What is it?

Let’s look at the JavaScript powering the site.

function login() {
    el = document.getElementById("lusername");
    el2 = document.getElementById("lpassword");
    el3 = document.getElementById("remember");
    url = "/index.php?o=login&user=" + encode(el.value) + "&pwd=" + md5(el2.value);
    if (el3 && el3.checked)
    {
        url += "&remember=yes";
    }
    initObj();
    showWait();
    if (xmlhttp!=null) {
      xmlhttp.onreadystatechange=_login;
      xmlhttp.open("GET",url,true);
      xmlhttp.setRequestHeader( "If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT" );
      xmlhttp.send(null);
    } else {
        url2 = "/index.php?o=login2&user=" + encode(el.value) + "&pwd=" + md5(el2.value);
        if (el3 && el3.checked)
        {
            url2 += "&remember=yes";
        }
        window.location=url2;
    }
}

Yes – it’s MD5ing the unsalted password test and submitting the hash.

A passive observer of the traffic can still just sniff a single login and re-use the hash to login to DSC. They don’t need to know the password.

A passive observer could obtain the password by cracking the MD5 hash. Because it is un-salted, the hash of can even be googled to find the password. Salting is essential when using a hash to store passwords.

Even if the attacker couldn’t get the password by passive observation and cracking, they could simply serve up a login page that submits the original password to a server under their control.

This isn’t the first, second, third, fourth or even fifth time I have seen this. It’s useless. Stop doing it!

Note that DSC are also passing sensitive parameters as GET rather than POST. This means that the hash is stored in your URL history, proxies between you and the server etc.

 

 

 

One thought on “Stop doing client-side password hashing

  1. Permalink  ⋅ Reply

    sanil

    October 16, 2017 at 10:09am

    How will this be cracked?
    You send (sha256(uuid+ sha256(password)) , uuid)
    uuid generated for each get/post at client. Has using sha256 javascript function

    The server only has sha256(password) strored

Leave a Reply to sanil Cancel reply

Your email will not be published. Name and Email fields are required.

This site uses Akismet to reduce spam. Learn how your comment data is processed.