Re: [whatwg] Hashing Passwords Client-side
Hi All, I believe there are three major discussions: 1. Is the security gain using client-side hashing worth the cost of implementation and education? 2. How would you implement client-side hashing? 3. How will incorrect deployment of client-side hashing affect security? I would like provide an updated solution to #2, which leads me to a follow-up question at the end of my e-mail. In the original proposal, I suggested adding an attribute @hash to input type=password tags. I now think this is ultimately a bad decision, because it doesn't provide a clear path for transition. I have attached a basic demo of a more robust implementation. The code of interest is: Username: input type=text name=fuserbr Password: input type=text name=fpass (intentionally a text field)br input type=hidden name=fpass.hash value=sha1,salt The JavaScript surrounding it simply implements what you would expect. Upon form submission, the JavaScript will read through all form names, and detect if there is a name.hash equivalent. If there is, it parses out the value field to extract the hashing algorithm, and salt (if no salt exists, it defaults to the origin). In the above example, the hash is sha1, and the salt is salt. It then performs the hash on the form value. Basically: form['fpass.hash'].value = sha1(form['fpass'].value + ':' + salt); Then it clears out the original value: form['fpass'].value = ''; The reason I chose this format was to enable a server-side framework to be able to detect all necessary information to perform the hashing itself if the client-side failed. If the client-side fails, all parameters are submitted to the server (input name to hash, hash function, and salt). If the salt is omitted, the server SHOULD be able to calculate its origin string. As an added benefit, the hash can now be applied to any form element. --- With that said, I think this brings up a follow-up question: Does this functionality need to be a part of the standard? I think at this point, it might make sense to leave it at the JavaScript level, and browsers do not need the functionality built into them. Thanks again for any comments. The attached code was written by me (including the sha1 implementation), and I hereby release it in the public domain. ~Sean On Mon, Jun 20, 2011 at 6:38 PM, Aryeh Gregor simetrical+...@gmail.com wrote: On Mon, Jun 20, 2011 at 4:40 AM, James Graham jgra...@opera.com wrote: FWIW I disagree. The same argument could be used against client-side form validation since some authors might stop doing proper server-side validation. I agree, HTML5 forms provide a minor net security loss. However, the loss is fairly small and is easily outweighed by the non-security advantages. Here we have a proposal that only has security benefits, so if it's a net security loss by even a small margin, or even if it's only a small security gain, it's not worth it.
Re: [whatwg] Hashing Passwords Client-side
On Mon, Jun 20, 2011 at 6:38 PM, Aryeh Gregor simetrical+...@gmail.com wrote: On Mon, Jun 20, 2011 at 4:40 AM, James Graham jgra...@opera.com wrote: FWIW I disagree. The same argument could be used against client-side form validation since some authors might stop doing proper server-side validation. I agree, HTML5 forms provide a minor net security loss. However, the loss is fairly small and is easily outweighed by the non-security advantages. Here we have a proposal that only has security benefits, so if it's a net security loss by even a small margin, or even if it's only a small security gain, it's not worth it. On 22 Jun 2011, at 16:35, Sean Connelly wrote: Hi All, I believe there are three major discussions: 1. Is the security gain using client-side hashing worth the cost of implementation and education? 2. How would you implement client-side hashing? 3. How will incorrect deployment of client-side hashing affect security? I'm going to avoid repeating my existing concerns that I've raised already, but I prepose the addition of questions 0 and 4: 0. Are there security gains from using client-side hash? 4. Will client-side hashing encourage some developers out of server-side hashing solutions? e.g. Is implementing this on the client-side going to imply that it's safe/sensible to do on the client-side? Since my comments I had researched the old WHATWG thread in which Maciej Stachowiak goes through some very well reasoned points which I feel stand in this discussion. See: Username: input type=text name=fuserbr Password: input type=text name=fpass (intentionally a text field)br input type=hidden name=fpass.hash value=sha1,salt The legacy-browser user will in this example be asked to enter a password in a text input, not a password input... intentional or typo? As an added benefit, the hash can now be applied to any form element. Is there a use-case for this? I am still very much of the opinion that client-side hashing is not useful nor beneficial to any site which runs SSL for personal/secure data and hashes on the serverside - anyone not doing this should be encouraged to do so, not offered an alternative which in my opinion (and Maciej's) is not a real security enhancement. I'm happy to answer more specifically but feel I'd be repeating what I said before, which wouldn't help anyone. Mat Carey
Re: [whatwg] Hashing Passwords Client-side
Hi Mat, The legacy-browser user will in this example be asked to enter a password in a text input, not a password input... intentional or typo? Intentional for the demo (as marked after the field). I forgot to mention as well: The demo is not production-level code. It incorrectly handles characters outside of the ASCII range, and has only been tested on Chrome 12. It likely has many bugs, and was written as a basic demonstration of the concept. I am still very much of the opinion that client-side hashing is not useful nor beneficial to any site which runs SSL for personal/secure data and hashes on the serverside - anyone not doing this should be encouraged to do so, not offered an alternative which in my opinion (and Maciej's) is not a real security enhancement. I'm happy to answer more specifically but feel I'd be repeating what I said before, which wouldn't help anyone. I agree. Client-side hashing has no security gain for a server running SSL and correctly performing server-side hashing. However, server-side hashing cannot be verified by the user. The user must take it on faith that the administrators have robust security procedures. Unfortunately, this is not the case on all servers. A benefit of using client-side hashing is that a user can verify that a server cannot insecurely store their password because the server never has access to the password. This can be circumvented using additional scripting, but the circumvented scripting would also need to be sent to the client, and could be inspected by impartial developers. Honest websites can implement client-side hashing. This is something that can be verified by third parties for a website. This ensures that the server CANNOT compromise plain-text passwords. The user still needs to take it on faith that the server implements additional server-side hashing, but that is the same state we are in right now. The benefit is that the user can verify that the server can never compromise their plain-text password. ~Sean On Wed, Jun 22, 2011 at 12:01 PM, Mat Carey m...@matcarey.co.uk wrote: On Mon, Jun 20, 2011 at 6:38 PM, Aryeh Gregor simetrical+...@gmail.com wrote: On Mon, Jun 20, 2011 at 4:40 AM, James Graham jgra...@opera.com wrote: FWIW I disagree. The same argument could be used against client-side form validation since some authors might stop doing proper server-side validation. I agree, HTML5 forms provide a minor net security loss. However, the loss is fairly small and is easily outweighed by the non-security advantages. Here we have a proposal that only has security benefits, so if it's a net security loss by even a small margin, or even if it's only a small security gain, it's not worth it. On 22 Jun 2011, at 16:35, Sean Connelly wrote: Hi All, I believe there are three major discussions: 1. Is the security gain using client-side hashing worth the cost of implementation and education? 2. How would you implement client-side hashing? 3. How will incorrect deployment of client-side hashing affect security? I'm going to avoid repeating my existing concerns that I've raised already, but I prepose the addition of questions 0 and 4: 0. Are there security gains from using client-side hash? 4. Will client-side hashing encourage some developers out of server-side hashing solutions? e.g. Is implementing this on the client-side going to imply that it's safe/sensible to do on the client-side? Since my comments I had researched the old WHATWG thread in which Maciej Stachowiak goes through some very well reasoned points which I feel stand in this discussion. See: Username: input type=text name=fuserbr Password: input type=text name=fpass (intentionally a text field)br input type=hidden name=fpass.hash value=sha1,salt The legacy-browser user will in this example be asked to enter a password in a text input, not a password input... intentional or typo? As an added benefit, the hash can now be applied to any form element. Is there a use-case for this? I am still very much of the opinion that client-side hashing is not useful nor beneficial to any site which runs SSL for personal/secure data and hashes on the serverside - anyone not doing this should be encouraged to do so, not offered an alternative which in my opinion (and Maciej's) is not a real security enhancement. I'm happy to answer more specifically but feel I'd be repeating what I said before, which wouldn't help anyone. Mat Carey
Re: [whatwg] Hashing Passwords Client-side
On 06/17/2011 08:34 PM, Aryeh Gregor wrote: On Thu, Jun 16, 2011 at 5:39 PM, Daniel Chengdch...@chromium.org wrote: A variation of this idea has been proposed in the past but was largely seen as undesirable--see http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2010-May/026254.html. In general, I feel like the same objections are still true of this proposal. This proposal is considerably better formulated than that one was. But yes, in the end, the only real benefit is that the user can confirm that their original plaintext password can only be retrieved by brute-forcing the hash, which protects them only against reuse of the password on different sites. So on consideration, it will probably lead more to a false sense of security than an actual increase in security, yes. It no longer seems like a good idea to me. FWIW I disagree. The same argument could be used against client-side form validation since some authors might stop doing proper server-side validation. But, as in that case, there are definite end user benefits — I consider limiting the scope of attacks to just a single site even in the face of password reuse to be a substantial win — and the authors who are most likely to get the server-side wrong are the same ones who are already storing passwords in plain text.
Re: [whatwg] Hashing Passwords Client-side
James Graham jgra...@opera.com schrieb am Mon, 20 Jun 2011 10:40:20 +0200: […] and the authors who are most likely to get the server-side wrong are the same ones who are already storing passwords in plain text. What reasoning is behind the assertion that those authors will use the provided client-side hashing facilities correctly, then? -- Nils Dagsson Moskopp // erlehmann http://dieweltistgarnichtso.net
Re: [whatwg] Hashing Passwords Client-side
On Mon, Jun 20, 2011 at 11:15 AM, Nils Dagsson Moskopp n...@dieweltistgarnichtso.net wrote: James Graham jgra...@opera.com schrieb am Mon, 20 Jun 2011 10:40:20 +0200: […] and the authors who are most likely to get the server-side wrong are the same ones who are already storing passwords in plain text. What reasoning is behind the assertion that those authors will use the provided client-side hashing facilities correctly, then? The fact that you can get minimally adequate functionality by just writing input type=password hash. ~TJ
Re: [whatwg] Hashing Passwords Client-side
On Mon, Jun 20, 2011 at 4:40 AM, James Graham jgra...@opera.com wrote: FWIW I disagree. The same argument could be used against client-side form validation since some authors might stop doing proper server-side validation. I agree, HTML5 forms provide a minor net security loss. However, the loss is fairly small and is easily outweighed by the non-security advantages. Here we have a proposal that only has security benefits, so if it's a net security loss by even a small margin, or even if it's only a small security gain, it's not worth it.
Re: [whatwg] Hashing Passwords Client-side
Sean, thanks for the suggestion. I have the following comments (my first comment on here, please instruct me if I get the style wrong): Why? The server can first try comparing the submitted password to the stored hash, then if that fails, hash the submitted password and compare that to the stored hash. Imagine the use case where a user joins a site on a legacy browser. The legacy browser sends the un-hashed password. They then attempt to login using a modern browser, which correctly hashes the password before sending it. The authentication will fail. I see a theoretical (but potentially major) problem accepting a) Accepting the hashed value blindly and b) Multiple passwords being accepted by the server. Currently my browser accepts the value password1 to an input name=pass type=password/ field, sends it in the POST data as pass=password1 and my serverside encrypts it to the (non-salted for ease of example) MD5 7c6a180b36896a0a8c02787eeafb0e4c. I find a lot of safety in the knowledge that I can't do anything malicious with a well-encrypted password even though I can read the encrypted value clearly in the DB. If, however, my browser made the request should include pass=7c6a180b36896a0a8c02787eeafb0e4c then I can copy and paste your hashed password into a curl request and log in as you, or do the same after manipulating the input/ field to remove hashing instructions. There needs to be a way for the server to distinguish when the hash has been correctly applied. As mentioned in a previous e-mail, I would imagine this work being done by a server-side framework automatically (eventually). There is a theoretical and pedantic use-case where I as a user can have a 32 char hex-decimal password which looks like an MD5. In this case how would any framework distinguish between my browser's MD5 and my intentionally written 32 char hex-deci password? To summarise: I feel that client-side hashing does not add the security it seems to on the surface and it would add some potential new issues. A developer who is able to store a password on the server-side should be encouraged to encrypt it on the serverside and I feel that this addition would encourage excited HTML5 on-lookers into what I would consider to be a false-sense of security. Mat Carey
Re: [whatwg] Hashing Passwords Client-side
Hi Mat, The simple solution to your problem is: The server SHOULD still hash the password it receives, before storing it in the database (i.e., the client would send a hashed password, and the server would hash the hash). Ideally, all servers should be doing this, with per-user salts. However, the reality is that many servers do not, or they use compromised hash functions (specifically, md5 with no salt). Your use case is possible, where a naive webmaster blindly copies the client-hashed value into the database. Just as webmasters today blindly copy the plain-text password into databases. The proposal helps to add security to these (unfortunate) use cases. Ideally, the client AND server would hash the password. We cannot control the server, but we can control the client. So this proposal attempts to standardize the client-side hashing. Please note an additional benefit: with this proposal, passwords are not sent as plain-text over HTTP. This improves security for many use cases (with the exception of HTTPS, and webmasters who already use JavaScript to locally hash the password before sending). There is a theoretical and pedantic use-case where I as a user can have a 32 char hex-decimal password which looks like an MD5. In this case how would any framework distinguish between my browser's MD5 and my intentionally written 32 char hex-deci password? In the proposal, I suggested a new header value to be sent by the client when the password is hashed: X-Password-Hash: 1 Tab Atkins Jr. suggested, instead of a new header, that the browser should synthesize a new form value to submit, which has the benefit that JavaScript could be used by legacy browsers to upgrade their behavior. Thank you for the feedback. ~Sean On Fri, Jun 17, 2011 at 5:17 AM, Mat Carey m...@matcarey.co.uk wrote: Sean, thanks for the suggestion. I have the following comments (my first comment on here, please instruct me if I get the style wrong): Why? The server can first try comparing the submitted password to the stored hash, then if that fails, hash the submitted password and compare that to the stored hash. Imagine the use case where a user joins a site on a legacy browser. The legacy browser sends the un-hashed password. They then attempt to login using a modern browser, which correctly hashes the password before sending it. The authentication will fail. I see a theoretical (but potentially major) problem accepting a) Accepting the hashed value blindly and b) Multiple passwords being accepted by the server. Currently my browser accepts the value password1 to an input name=pass type=password/ field, sends it in the POST data as pass=password1 and my serverside encrypts it to the (non-salted for ease of example) MD5 7c6a180b36896a0a8c02787eeafb0e4c. I find a lot of safety in the knowledge that I can't do anything malicious with a well-encrypted password even though I can read the encrypted value clearly in the DB. If, however, my browser made the request should include pass=7c6a180b36896a0a8c02787eeafb0e4c then I can copy and paste your hashed password into a curl request and log in as you, or do the same after manipulating the input/ field to remove hashing instructions. There needs to be a way for the server to distinguish when the hash has been correctly applied. As mentioned in a previous e-mail, I would imagine this work being done by a server-side framework automatically (eventually). There is a theoretical and pedantic use-case where I as a user can have a 32 char hex-decimal password which looks like an MD5. In this case how would any framework distinguish between my browser's MD5 and my intentionally written 32 char hex-deci password? To summarise: I feel that client-side hashing does not add the security it seems to on the surface and it would add some potential new issues. A developer who is able to store a password on the server-side should be encouraged to encrypt it on the serverside and I feel that this addition would encourage excited HTML5 on-lookers into what I would consider to be a false-sense of security. Mat Carey
Re: [whatwg] Hashing Passwords Client-side
Thanks Sean, The server SHOULD still hash the password it receives, before storing it in the database (i.e., the client would send a hashed password, and the server would hash the hash) I agree, but if the server-side hashing should be implemented regardless of whether the client-side hashes then are we truly adding a feature? If not then I fear we are merely adding issues caused by legacy browsers co-existing with current/future browsers as highlighted in your original post (disadvantage 2 stated Server-side code might be complicated for dealing with legacy, non-hashing browsers). Your use case is possible, where a naive webmaster blindly copies the client-hashed value into the database. Just as webmasters today blindly copy the plain-text password into databases. The proposal helps to add security to these (unfortunate) use cases. My (potentially controversial) opinion is that even though these 'unfortunate' cases may seem to benefit from a client-side hash the same webmasters may be unaware of the need for legacy support and that client-side hashing will not secure their passwords at a DB/HTTP level. I fear we would be encouraging more webmasters/developers to follow the client-side hashing will be to the detriment of server-side hashing. A developer who is able to implement a database storage in a server-side language should be able to encrypt in that language, if this is true they should be strongly encouraged to do this on the server-side and not confused by adding client-side hashing. I feel client-side hashing implies to the partially-informed webmaster/developer that server-side hashing can be replaced by client-side hashing which would lead to more security holes across the web. the browser should synthesize a new form value to submit, which has the benefit that JavaScript could be used by legacy browsers to upgrade their behavior. There is no guarantee that your user is using Javascript, which means this upgrade would not be available and it accidentally becomes the same as TJ's suggestion: (from Tab Atkins Jr. 16th June 2011 22:08:36 GMT+01:00) you can just ignore legacy browsers and store the passwords directly. Those older browsers will just have security vulnerabilities. The problem I see here is that I can register using one browser (e.g. FF3.6 with JS off or an accessible browser which doesn't run JS) and my password is sent (and potentially stored) in plain text (described as 'just have security vulnerabilities'), then try to login in after the FF comes out supporting this feature and I will be unable to log in because my hashed password that is now sent does not equate to the unhashed version which is stored. This problem also exists the other way around and pushes the developer/webmaster into the position where they need to allow pre-hashed and plain-text passwords to be sent from the browser. I feel a can of worms could be opened and not easily closed. I am of the opinion that the cross-browser/legacy-browser issues that _could_ come from this are very hard to recover from and _even if_ it were fully cross-browser and legacy-browser compatible I don't see a strong enough reason to rely upon it as users would be able to tamper with the fields and request data mitigating any potential security benefit. NOTE: I am assuming it goes without saying that SSL should be used for registrations, logins etc. _even if_ this client-side hashing is present. To qualify some of my position I feel it's worth mentioning that I have consulted on a large site (which was created years before I was involved) where there are is a mix of MD5'd and plain text passwords - it's a situation I would not want to encourage anyone to get themselves into and some of the circumstances I have commented on have been real problems for that site. Mat Carey
Re: [whatwg] Hashing Passwords Client-side
On Thu, Jun 16, 2011 at 5:39 PM, Daniel Cheng dch...@chromium.org wrote: A variation of this idea has been proposed in the past but was largely seen as undesirable--see http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2010-May/026254.html. In general, I feel like the same objections are still true of this proposal. This proposal is considerably better formulated than that one was. But yes, in the end, the only real benefit is that the user can confirm that their original plaintext password can only be retrieved by brute-forcing the hash, which protects them only against reuse of the password on different sites. So on consideration, it will probably lead more to a false sense of security than an actual increase in security, yes. It no longer seems like a good idea to me. On Thu, Jun 16, 2011 at 7:28 PM, Sean Connelly s...@pbwhere.com wrote: This strikes me as abnormal; I'm not aware of the browser injecting form values for any other functionality. However, one benefit of this method is that a developer can create a JavaScript file to drop in to pages that will perform hashing for legacy browsers. The JavaScript could check to see if the browser performs hashing, and if not, add listeners on all form submissions. It could hash the password fields prior to submission, and inject the the synthesized form value. This would provide a path for legacy support. Side point: there are some existing cases where magic form values are injected. input type=image submits .x and .y values, for instance. The disadvantage to this approach is that, years from now, the default may be compromised (like md5). Another side point: MD5 is actually not compromised for the purposes of password storage. There are collision attacks, but no preimage attacks. Even MD4, which has had a working collision attack since 1995, still has nothing more than a theoretical preimage attack. So this isn't a huge worry in practice. Collision attacks aren't relevant to our use-case. (But don't use MD5 for things like certificate signing where collision resistance is important!) Yes, the site should. In fact, the webmaster should be doing additional hashing on the server side. However, we can't control that. If the webmaster is clueless and just stores the data directly (which webmasters do in the real world, unfortunately), at the very least, this solution will improve security. Only in one very narrow case: it will prevent a passive network attacker or someone who compromises the database from learning the original plaintext password without brute-forcing the hash. It will not stop them from logging in as the user on the same site, only from logging in as the user on other sites. On the other hand, administrators would be likely to assume that because the passwords now look like gibberish, they must be secure, which is totally wrong. Proper use of server-side hashing will leak no info about passwords to an attacker at all without brute-forcing, and proper use of client+server-side hashing will leak no info about passwords to a passive network attacker without brute-forcing. Making it easy to do hashing badly will discourage people from doing it well. I've read some of the thread... Please keep in mind that my proposal is not a catch-all solution to password management. It is intended to solve one specific problem. It is intended to be incremental progress. The problem is it solves much less of the problem than hashing is supposed to solve, but to the uninitiated it looks the same as a real hashing scheme. It gives a false sense of security that probably outweighs any actual security benefit (which is very limited).
Re: [whatwg] Hashing Passwords Client-side
Thank you for your input. I had forgotten about the input type=image fields. Yes, as these issues have been brought up, I've also imagined additional disadvantages as well. For documentation purposes, here are some additional items to consider if this topic comes up again: 1. I'm not clear how a server-side framework could automatically apply hashes to password fields from legacy browsers. The framework would not be able to identify which form values were password fields (and therefore, which ones it would need to hash). 2. Some use cases for password fields are simply to mask what the user is typing, and SHOULDN'T be hashed. For example, I have seen financial/government sites that mask SSN input through a password field. Their intention is never to hash the value. 3. As Mat brought up, I think it is reasonable to imagine webmasters who think client-side hashing is good enough. This can give them a false sense of security. Ultimately, I think my next step is to develop a JavaScript library that implements the behavior (by perhaps injecting .hash form values). This can help me to figure out the details in private, and see if this is worthwhile to include in the HTML standard. I may return to WHATWG in the future with my results if I feel there is a tangible benefit. Thanks again for everyone who contributed to help me think through this problem. ~Sean On Fri, Jun 17, 2011 at 2:34 PM, Aryeh Gregor simetrical+...@gmail.comwrote: On Thu, Jun 16, 2011 at 5:39 PM, Daniel Cheng dch...@chromium.org wrote: A variation of this idea has been proposed in the past but was largely seen as undesirable--see http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2010-May/026254.html. In general, I feel like the same objections are still true of this proposal. This proposal is considerably better formulated than that one was. But yes, in the end, the only real benefit is that the user can confirm that their original plaintext password can only be retrieved by brute-forcing the hash, which protects them only against reuse of the password on different sites. So on consideration, it will probably lead more to a false sense of security than an actual increase in security, yes. It no longer seems like a good idea to me. On Thu, Jun 16, 2011 at 7:28 PM, Sean Connelly s...@pbwhere.com wrote: This strikes me as abnormal; I'm not aware of the browser injecting form values for any other functionality. However, one benefit of this method is that a developer can create a JavaScript file to drop in to pages that will perform hashing for legacy browsers. The JavaScript could check to see if the browser performs hashing, and if not, add listeners on all form submissions. It could hash the password fields prior to submission, and inject the the synthesized form value. This would provide a path for legacy support. Side point: there are some existing cases where magic form values are injected. input type=image submits .x and .y values, for instance. The disadvantage to this approach is that, years from now, the default may be compromised (like md5). Another side point: MD5 is actually not compromised for the purposes of password storage. There are collision attacks, but no preimage attacks. Even MD4, which has had a working collision attack since 1995, still has nothing more than a theoretical preimage attack. So this isn't a huge worry in practice. Collision attacks aren't relevant to our use-case. (But don't use MD5 for things like certificate signing where collision resistance is important!) Yes, the site should. In fact, the webmaster should be doing additional hashing on the server side. However, we can't control that. If the webmaster is clueless and just stores the data directly (which webmasters do in the real world, unfortunately), at the very least, this solution will improve security. Only in one very narrow case: it will prevent a passive network attacker or someone who compromises the database from learning the original plaintext password without brute-forcing the hash. It will not stop them from logging in as the user on the same site, only from logging in as the user on other sites. On the other hand, administrators would be likely to assume that because the passwords now look like gibberish, they must be secure, which is totally wrong. Proper use of server-side hashing will leak no info about passwords to an attacker at all without brute-forcing, and proper use of client+server-side hashing will leak no info about passwords to a passive network attacker without brute-forcing. Making it easy to do hashing badly will discourage people from doing it well. I've read some of the thread... Please keep in mind that my proposal is not a catch-all solution to password management. It is intended to solve one specific problem. It is intended to be incremental progress. The problem is it solves much less of the
[whatwg] Hashing Passwords Client-side
Hi All, I've just joined the mailing list, and this is my first time in such an environment, so I apologize ahead of time if I'm not using the list correctly. I would like to propose an idea for inclusion in future generations of HTML, or at least, I am curious if such an idea has already been discussed. Thank you for reading and providing any help, or suggestions. Thanks! ~Sean -- ## Problem Attempting to Solve: Websites commonly need to store login information for users. Web developers may naively store the password in non-secure ways (plain-text, md5 with no salt, etc). It has become common for hacker groups to target websites to get a data-dump of all users/passwords, and using this information, try to compromise accounts on other websites. One example below: http://arstechnica.com/security/news/2011/06/lulzsec-rampage-continues-62k-e-mails-and-passwords-cia-under-attack.ars ## Proposed Solution: Add an attribute to input type=password called hash. For example: input type=password hash=sha1 salt=something This will indicate to the browser that it needs to hash the value locally before sending it to the server. This hash should include a site-specific salt, so that the same password typed on two different sites will hash to different values. I propose the default salt to be the origin as an ASCII string (protocol + host + port, ex: http://example.com:80;), and the default hash to be none (in order for backward compatibility). By hashing the password before transmitting to the host, the host is never actually aware of the password typed by the user. The host can treat it as a normal password, and store it as it would normally store any other password. Authentication can still be performed because the host would check to see if the hashes matched. In order to deal with migration correctly, the browser will also need to communicate to the server that it correctly performed the hash. I propose a new header for the browser to send: X-Password-Hash: 1 If the browser does not send this header, then the host should expect to receive an unhashed, plain-text password. Each available hash function (sha1, sha2, etc), will have to be identified in the spec, along with the format the hash should be transmitted in (lower-case hex dump?). ## Benefits: 1. Host never has access to actual password (as long as user has a modern browser) 2. If the host is compromised, hackers may be able to takeover the account on the server, but will not be able to take over accounts on different servers even if the user uses the same password (because the hackers will only have access to the hashed password with site-specific salts) 3. Plain-text passwords cannot be sniffed over HTTP 4. Easy for webmasters to upgrade for additional security benefit ## Disadvantages: 1. Host cannot validate password requirements (ex: 2 upper case, 2 lower case, 2 special characters, password length, etc) 2. Server-side code might be complicated for dealing with legacy, non-hashing browsers ## Questions: 1. How to deal with the character encoding of the page correctly? Should everything be converted to UTF-8 before the hash is calculated? 2. What level of access should JavaScript have? Should it have access to read the plain password, or should it only be able to read the hashed value?
Re: [whatwg] Hashing Passwords Client-side
On Thu, Jun 16, 2011 at 12:59 PM, Sean Connelly s...@pbwhere.com wrote: I've just joined the mailing list, and this is my first time in such an environment, so I apologize ahead of time if I'm not using the list correctly. Nope, you did pretty good. You listed a problem, and then proposed a solution to it. Most people forget to do that first part when they start posting. ^_^ ## Problem Attempting to Solve: Websites commonly need to store login information for users. Web developers may naively store the password in non-secure ways (plain-text, md5 with no salt, etc). It has become common for hacker groups to target websites to get a data-dump of all users/passwords, and using this information, try to compromise accounts on other websites. One example below: http://arstechnica.com/security/news/2011/06/lulzsec-rampage-continues-62k-e-mails-and-passwords-cia-under-attack.ars Or, more concretely, you *never* actually need to store the password that someone is using. Like, ever. You should *always* immediately hash the password with a good cryptographic hash, and only store the hashed value. The only thing you should ever need to do with the plaintext password is pass it to your hashing function, and then immediately forget it. However, a non-trivial number of servers don't do this, which is the source of constant security headaches. ## Proposed Solution: Add an attribute to input type=password called hash. For example: input type=password hash=sha1 salt=something This will indicate to the browser that it needs to hash the value locally before sending it to the server. This hash should include a site-specific salt, so that the same password typed on two different sites will hash to different values. I propose the default salt to be the origin as an ASCII string (protocol + host + port, ex: http://example.com:80;), and the default hash to be none (in order for backward compatibility). By hashing the password before transmitting to the host, the host is never actually aware of the password typed by the user. The host can treat it as a normal password, and store it as it would normally store any other password. Authentication can still be performed because the host would check to see if the hashes matched. In order to deal with migration correctly, the browser will also need to communicate to the server that it correctly performed the hash. I propose a new header for the browser to send: X-Password-Hash: 1 If the browser does not send this header, then the host should expect to receive an unhashed, plain-text password. Each available hash function (sha1, sha2, etc), will have to be identified in the spec, along with the format the hash should be transmitted in (lower-case hex dump?). Personally, I'd prefer the information be transmitted via another (browser-synthesized) form input, as it's usually much easier to read form inputs than header values. (Also, X-* headers are an antipattern. The X- prefix serves absolutely no purpose. This is just a naming issue and irrelevant to your proposal; I just wanted to inform you in case you're ever directly responsible for naming a header in the future.) I like your idea for the default salt. We might be able to hook off of slightly better concepts (use the origin directly?) but the idea is sound. For the @hash attribute, we should just specify a single hash for now, the strongest we believe we can rely on. Then we can make it the default value, so utilizing this would be as simple as input type=password hash. (You don't need a none value, since the lack of the attribute would indicate that.) If this becomes inadequate in the future, we can just add more values. ## Benefits: 1. Host never has access to actual password (as long as user has a modern browser) 2. If the host is compromised, hackers may be able to takeover the account on the server, but will not be able to take over accounts on different servers even if the user uses the same password (because the hackers will only have access to the hashed password with site-specific salts) 3. Plain-text passwords cannot be sniffed over HTTP 4. Easy for webmasters to upgrade for additional security benefit For #3, you can still sniff the hashed password over HTTP, and then just submit that manually. But point #2 mitigates the damage that would do, unlike the current state of affairs. ## Disadvantages: 1. Host cannot validate password requirements (ex: 2 upper case, 2 lower case, 2 special characters, password length, etc) This is a benefit, actually. Password requirements are, nearly uniformly, absolutely horrendous for security in practice. 2. Server-side code might be complicated for dealing with legacy, non-hashing browsers Only for the transition period. Afterwards, you can just ignore legacy browsers and store the passwords directly. Those older browsers will just have security vulnerabilities. Of course, server-side
Re: [whatwg] Hashing Passwords Client-side
On Thu, Jun 16, 2011 at 3:59 PM, Sean Connelly s...@pbwhere.com wrote: ## Proposed Solution: Add an attribute to input type=password called hash. For example: input type=password hash=sha1 salt=something How does this solve the problem? Do you expect it to help because users will be able to see which sites are using unhashed passwords, and complain so that the site admins fix it? This will indicate to the browser that it needs to hash the value locally before sending it to the server. This hash should include a site-specific salt, so that the same password typed on two different sites will hash to different values. I propose the default salt to be the origin as an ASCII string (protocol + host + port, ex: http://example.com:80;), and the default hash to be none (in order for backward compatibility). Salting with something that's not included in the database is not a good idea. It means that if the site author isn't extremely careful to provide the same salt every time, login will fail. If the author can provide a salt, it should default to the empty string, and it should also be included in the submitted hash. E.g., instead of submitting 0123456789abcdef, submit 0123456789abcdef:salt or something as the password. That way, if anything is stored with the wrong salt, it will be easily detectable on the server side. Also, the site should really be using a per-user salt. Otherwise, someone with database access can immediately tell which users have the same passwords. For large databases, this would allow recovering a lot of the passwords very cheaply by frequency analysis. However, it's probably not practical to do a client-side per-user salt. One thing salting would be good for is some kind of nonce scheme, where you compute the hash, salt it, and then hash it again with a one-time salt. If the server discards the salt after using it once, the password hash sniffed off the wire will be useless to the attacker. (Of course, this only works for login, not registration.) However, you need fairly complicated server-side logic to support this, and it's not trivial for users to notice whether the nonce is reusable, so I don't know if it's useful to support this. So I think salting can just be omitted here, at least for a first draft. Site-wide salts don't buy you very much, and clients can't easily do any other kind of salt. The salt attribute as you proposed it won't significantly increase security, but it will make people think they're doing proper salting when they aren't. Not supporting salts does leave us open to rainbow tables, unfortunately, but I don't see a good way to fix that from the client side. In order to deal with migration correctly, the browser will also need to communicate to the server that it correctly performed the hash. Why? The server can first try comparing the submitted password to the stored hash, then if that fails, hash the submitted password and compare that to the stored hash. That way, you don't need to submit out-of-band information. I propose a new header for the browser to send: X-Password-Hash: 1 If we did want a new header, it shouldn't start with X-. We'd be standardizing it, after all. We'd probably want to submit it as extra magic form fields, too, not an HTTP header. I'd suggest a way to allow authors to iterate the hashing. For password hashes, you shouldn't use a hash applied only once. Instead, you should hash the same value thousands of times. That way, an attacker who gets the database will have to spend thousands of times the CPU effort to crack the hashes. I suggest again that the number of iterations be adjoined to the password in some fashion, so that it's easy to migrate passwords if you increase the number of iterations. I'd also suggest a high number of iterations by default, so that a low-end client would take 10-100 ms to execute the hashes. There should be a minimum number of iterations too, to help avert authoring errors. 1. Host never has access to actual password (as long as user has a modern browser) 2. If the host is compromised, hackers may be able to takeover the account on the server, but will not be able to take over accounts on different servers even if the user uses the same password (because the hackers will only have access to the hashed password with site-specific salts) These are not benefits relative to doing it on the server side. 3. Plain-text passwords cannot be sniffed over HTTP This is a definite benefit. Barring one-time salts, the attacker could still authenticate as the user by just submitting the same hash, but it's still good if they can't retrieve the plaintext password. If they don't know the original password, they can't attack other sites where the user has an account. 4. Easy for webmasters to upgrade for additional security benefit It wouldn't be any easier than with server-side hashing. In fact it might be mildly harder. But it would be *detectable*, which I
Re: [whatwg] Hashing Passwords Client-side
A variation of this idea has been proposed in the past but was largely seen as undesirable--see http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2010-May/026254.html. In general, I feel like the same objections are still true of this proposal. Daniel On Thu, Jun 16, 2011 at 14:08, Tab Atkins Jr. jackalm...@gmail.com wrote: On Thu, Jun 16, 2011 at 12:59 PM, Sean Connelly s...@pbwhere.com wrote: I've just joined the mailing list, and this is my first time in such an environment, so I apologize ahead of time if I'm not using the list correctly. Nope, you did pretty good. You listed a problem, and then proposed a solution to it. Most people forget to do that first part when they start posting. ^_^ ## Problem Attempting to Solve: Websites commonly need to store login information for users. Web developers may naively store the password in non-secure ways (plain-text, md5 with no salt, etc). It has become common for hacker groups to target websites to get a data-dump of all users/passwords, and using this information, try to compromise accounts on other websites. One example below: http://arstechnica.com/security/news/2011/06/lulzsec-rampage-continues-62k-e-mails-and-passwords-cia-under-attack.ars Or, more concretely, you *never* actually need to store the password that someone is using. Like, ever. You should *always* immediately hash the password with a good cryptographic hash, and only store the hashed value. The only thing you should ever need to do with the plaintext password is pass it to your hashing function, and then immediately forget it. However, a non-trivial number of servers don't do this, which is the source of constant security headaches. ## Proposed Solution: Add an attribute to input type=password called hash. For example: input type=password hash=sha1 salt=something This will indicate to the browser that it needs to hash the value locally before sending it to the server. This hash should include a site-specific salt, so that the same password typed on two different sites will hash to different values. I propose the default salt to be the origin as an ASCII string (protocol + host + port, ex: http://example.com:80;), and the default hash to be none (in order for backward compatibility). By hashing the password before transmitting to the host, the host is never actually aware of the password typed by the user. The host can treat it as a normal password, and store it as it would normally store any other password. Authentication can still be performed because the host would check to see if the hashes matched. In order to deal with migration correctly, the browser will also need to communicate to the server that it correctly performed the hash. I propose a new header for the browser to send: X-Password-Hash: 1 If the browser does not send this header, then the host should expect to receive an unhashed, plain-text password. Each available hash function (sha1, sha2, etc), will have to be identified in the spec, along with the format the hash should be transmitted in (lower-case hex dump?). Personally, I'd prefer the information be transmitted via another (browser-synthesized) form input, as it's usually much easier to read form inputs than header values. (Also, X-* headers are an antipattern. The X- prefix serves absolutely no purpose. This is just a naming issue and irrelevant to your proposal; I just wanted to inform you in case you're ever directly responsible for naming a header in the future.) I like your idea for the default salt. We might be able to hook off of slightly better concepts (use the origin directly?) but the idea is sound. For the @hash attribute, we should just specify a single hash for now, the strongest we believe we can rely on. Then we can make it the default value, so utilizing this would be as simple as input type=password hash. (You don't need a none value, since the lack of the attribute would indicate that.) If this becomes inadequate in the future, we can just add more values. ## Benefits: 1. Host never has access to actual password (as long as user has a modern browser) 2. If the host is compromised, hackers may be able to takeover the account on the server, but will not be able to take over accounts on different servers even if the user uses the same password (because the hackers will only have access to the hashed password with site-specific salts) 3. Plain-text passwords cannot be sniffed over HTTP 4. Easy for webmasters to upgrade for additional security benefit For #3, you can still sniff the hashed password over HTTP, and then just submit that manually. But point #2 mitigates the damage that would do, unlike the current state of affairs. ## Disadvantages: 1. Host cannot validate password requirements (ex: 2 upper case, 2 lower case, 2 special characters, password