Re: Securing Password Inputs

That's a pretty good summary, though I think it needs a few corrections.
1. My original proposal is just to hash passwords on the client side. The extended hashing  on the server side is something that can be done later. The important bit here is that it is transparent to the server if it is prehashed or not. Either way the attacker has to defeat at least 2 hashes. The proper solution is to still salt and hash what you got from the browser. 

2. As you point out if you are serving two domains this can cause a problem that an attribute is needed to fix. However this is only the case if the POST action needs to be accessible both domains. If you are on bar.com and use "http://foo.com/login.php"  as your action then you have already solved the problem. I expect this to be the case for aliased domains. 

3. As the problem exists, even at large sites, the education factor is not winning. I should be able to know my passwords are stored properly. With this feature I can know that. As it stands now I do not know until after a breach, and after the company acknowledges the breach. It took LinkedIn long enough (hours) that by the time it was acknowledged 160,000 accounts were compromised. 


4. This sucks and someone needs to do something about it. The browser people have been very pro-active and there are far fewer browser platforms (Opera, IE, Chrome(webkit), Safari(webkit), Firefox (gecko)) than there are websites to screw this up. That's why I am advocating a client-side approach.




________________________________
 From: Thomas A. Fine <fine@head.cfa.harvard.edu>
To: public-html-comments@w3.org 
Sent: Monday, September 3, 2012 9:44 PM
Subject: Re: Securing Password Inputs
 
Let's reset.

Where can passwords be compromised?

Step 1. Data entry.  Passwords can be trapped by key loggers, and various other nefarious attacks like shared libraries and things that take over the kernel or some part of the application.  HTML can not fix anything here.

Step 2. Data transmission.  Passwords can be intercepted as they travel over the computer network.  SSL takes care of this.  If a developer fails to use HTML for password entry forms, any kind of hashing method used on the client end will be useless, as the evildoer will get to see whatever it is that is needed for login, whether that thing is a thing that is clear text or has been hashed once or a million times.  Whatever it is they can see it and use it.

Step 3. Data storage.  I think this is what you have been worrying about.  Dumb developers store the password as transmitted to them, so that if hackers manage to steal their database, they get all these usernames and passwords.  Worse, most of them will most likely work as is on other websites.

The correct fix is for the developer to stop storing plain passwords, and store a hash instead.  This way if hackers get the stored passwords, they are only useful if the hacker can manage to invert the hash. Depending on the hashing algorithm this may or may not be feasible.  But here's the critical part.  If the hacker can not invert
the hash, these password hashes are useless.  They can not be used to
login here ore anywhere else.

What you are proposing is that, in case developers are too stupid to do things correctly, the client performs some kind of hash prior to transmitting the password.  The first problem here (compared to the correct solution) is that the hash no longer provides protection, because now the hash itself can be used to log in.  In the correct solution, the real password must be sent to login.  In your proposed band-aid, the hash can be used to log in.  All you've done is create a new password of a different form.  It's just as vulnerable as ever during steps one and two above.  During step one when the user enters their real password, a hacker can watch the web browser perform the hash, and then grab the hash from memory.  A hacker can also grab the hash during step two, transmission.  And in both cases, it can be used to log in to the website, just as a plain text password could be.  This is no better than the plaintext passwords stored in clear text
 on the server.

But you say the server could hash the hash before it stores it.  True, but if they knew to do that, then they would have known to do it with the plain text password and the problem you are trying to solve doesn't exist at all.

You also point out that instead of just hashing the password you could hash user:password:domain, and this would prevent hackers from being able to notice two users with the same password (because user is hashed), or from using this password on another domain (because server domain is hashed).  But how would this be implemented in HTML.  First, you can't actually just use the domain.  We have a server that answers to foo.com, bar.com, www.foo.com, www.bar.com, and www.foo.bar.com.  So if the user logs in once from one domain, then their password won't work from the other?  The only feasible fix is to add a HTML attribute that lets the web developer specify a value for "domain" in the hashed string.  But what if they don't because they're a dumb developer?  A smart developer is already hashing the password so we don't care about them.  The dumb developer will screw this up too, and you end up with some default which will either break their site if
 accessed by more than one domain, or fail to give any cross-site password reuse protection (e.g if the default domain is the empty string).

The situation is the same for the user.  How does the web form know what the user name is?  You have to specify an attribute in the HTML of another form field to pull this from.  You can't realistically suggest that some hackish guess of looking for fields named "user", "name", "login", "email", etc. be an established part of the HTML standard. So a dumb developer will skip this step, and lose the protection here too.

Your proposed goal as I understood it was to protect passwords even on sites written by dumb developers.  The problem is, the solution is unworkable.  Even if by some miracle a developer was smart enough to use this new hash setup correctly specifying the user field and domain and hashing algorithm to use, you still have a "solution" which is not as good as the developer who simply hashes the passwords at the server end.

To reiterate, hashing on the server end requires the hacker to enter a string that is different than what is stored in the database.  Hashing on the client end allows the hacker to use the string stored in the database for login.  The rest of what you've said is just useless obfuscation.

It's just not possible to legislate away stupidity.

     tom

Received on Tuesday, 4 September 2012 13:31:56 UTC