Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Find a way to avoid exposing a user password to the web page #96

Open
dbates-wk opened this issue Jul 13, 2017 · 9 comments
Open

Find a way to avoid exposing a user password to the web page #96

dbates-wk opened this issue Jul 13, 2017 · 9 comments

Comments

@dbates-wk
Copy link

(Let me know if this issue would be more appropriate to discuss in the context of the Web Authentication spec.)

It would be great if the Credential Management spec. had guarantees that it would never expose the user's password to the web page or web server. If we made that a hard constraint can we come up with a solution?

I have not thought this through completely. Could the keychain management aspects of the Credential Management API be combined with an implementation of a Secure Remote Password protocol and the concept of an opaque password field to avoid the need to ever expose the actual password to the web page/web server?

@dbates-wk
Copy link
Author

CC @mikewest

@mikewest
Copy link
Member

Could the keychain management aspects of the Credential Management API be combined with an implementation of a Secure Remote Password protocol and the concept of an opaque password field to avoid the need to ever expose the actual password to the web page/web server?

This seems like a laudable goal. Do y'all have some concrete ideas?

Off the top of my head, I can imagine something that hashes a challenge and the password locally, even a really naive approach like:

navigator.credentials.get({
    'hashedPassword': { 'challenge': 'abcdefg', 'count': 10000 }
}).then(c => {
    // `c` is an `HashedPassword` object containing: {
    //    'challenge': 'abcdefg',
    //    'response': PBKDF2('abcdefg', password, 10000)
    //  }
});

A problem, though, is that this scheme would require the server to have plaintext access to the password in order to verify the hash (if they stored only hashed password in their local database, they wouldn't be able to combine the pasword with the challenge in any reasonable way). That might actually be worse than status quo, where the server could only have access in the context of a POST response.

I'd be really interested in hearing other ideas that might mitigate that risk. Maybe we could support a particular hashing mechanism and have the server pass in enough information for us to replicate it client-side? (e.g. sha256(hashAlgorithm(options, options, options, password) + challenge))?

CC @battre @hillbrad

@battre
Copy link
Collaborator

battre commented Jul 14, 2017

Instead of storing the password, the website could store a hash of the password and ask to provide PBKDF2('abcdefg', hash(password), 10000), right?

Another, much more fancy approach would be around zero-knowledge proofs. Paul Crowley pointed me to http://grouper.ieee.org/groups/1363/passwdPK/contributions.html and suggested PAK-Z+ (or a post-quantum secure version) as a zero-knowledge proof of knowing credentials. Full disclaimer: I have not studied this material so the following may be wrong. My understanding is that the user would not type the password into a website but into a native password dialog. Even if I type my google password into the naive dialog of phishing.com, nothing bad would happen.

But frankly, I think this is a gradual process. I don't think that we get very far if we expect sites to rebuild their entire auth infrastructure in one step.

@dbates-wk
Copy link
Author

CC @johnwilander

@mikewest
Copy link
Member

Ping? I think this is an interesting conversation; it'd be good if we could continue it. :)

@dbates-wk
Copy link
Author

I have not had a chance to finish reading the existing literature on the Secure Remote Password protocol and zero-knowledge proofs. From my initial readings into these topics they seem the most applicable to support authentication without exposing credentials. It would be great if someone more familiar with these topics would be willing to give a presentation on them and/or help determine the feasibility of integrating them into a web browser.

@dbates-wk
Copy link
Author

But frankly, I think this is a gradual process. I don't think that we get very far if we expect sites to rebuild their entire auth infrastructure in one step.

I hope that we can come up with a solution that minimizes the server-side implementation effort. I am willing to trade requiring web site operators to put more effort than the status quo when it comes to transmission of a user's password in exchange for a secure and great user experience. I suspect web site operators will be willing to make such an investment if the benefits are the following:

  • Guaranteed secure authentication
    • Password not accessible even if page has XSS vulnerability
    • Password not accessible under passive and active network attacks
      • Complete compromise of server's password database has little to no value.
  • Ability to save, retrieve, and update credentials in the user-agent's credential store.

@battre
Copy link
Collaborator

battre commented Aug 25, 2017

Apologies for the radio silence... Summer vacation and moving...

Do I see it correct that the necessary components for this would be:

  1. a mechanism to fully opt-out of autofill based password management
  2. a mechanism to proof knowledge of the password to the server
  3. a mechanism to enter passwords into native UI

For 1., I am thinking of something along the lines of HSTS that opts out on the full domain (and probably other sub-domains). Without that, the site risks that any non-protected site gets a password form injected via XSS that discloses the password on autofill.

For 2., we probably need something more advanced than the algorithm proposed above to protect against phishing and active network attacks.

For 3., we need to think of the bootstrapping. How do we deal with getting the credentials into the system? How do we deal with the set of users that don't want to store passwords in a password manager? I think this has to be non-spoofable native UI, which may cause some resistance from sites and users.

Advantages of this approach

  • Does not require special hardware.

Issues of the approach

  • Chrome on Android does not have un-spoofable UI, I don't know about other mobile browsers.
  • Requires websites to rewrite their auth-stack. Depending on how fancy the algorithms go, this may be difficult work.
  • Still no protection against local attackers, who can read persisted passwords / capture key presses / ...
  • The proposed hashing algorithm provides no full protection against XSS / active network access unless we add extra logic (an attacker may intercept a challenge from the server, inject that into an attacked page, get it answered and capture the result).
  • The proposed hashing algorithm provides no protection against phishing.
  • Compromise of server's password database is still problematic.

I think that the Password-Based Public-Key Cryptography work can address the XSS, active network and phishing attacks. But then the question is whether the effort for websites to implement the algorithms and the fact that users need to enter their credentials into native UI become prohibitive.

@backkem
Copy link

backkem commented May 6, 2018

I feel the recent Twitter debacle illustrates the need for this type of mechanism.
Some thoughts:

  • Password input: A generic way to enable password input that is shielded from the web page. I see two options:
    • Predefined input types that are baked into the browser, E.g.: Password, pin, dongle, ... The web page could specify the allowed types and minimum strength requirements.
    • Some form of sand-boxed element that allows the webpage to define the input. It may however be tricky to balance flexibility and security.
  • Proof: The user has to prove their identity to the server without the server knowing the password. As mentioned before, this type of proof is called a zero knowledge proof. This allows the server to only determine if the identity is valid or not (binary) based on the user's public keys. As the name would suggest, no other information is shared. This is a vibrant research topic in the blockchain world. zkSNARKs are a popular variant of this type of proof, see scipr-lab/libsnark. They allow non-interactive proofs, thus avoiding a challenge-response scheme.
  • XSS attacks would not be possible. Since the web page has zero knowledge, there is nothing to intercept. Assuming the attack can't access the (native or sand-boxed) password input.
  • The same is true for the server password database. There would be no such thing. One could only steal the public keys used by the proof which hold very tittle value. They only provide you with the means to verify a user's identity, not falsify it.
  • The browser could allow for a transparent mode where a proof is generated by a 3rd party and passed along to the web page. The third party could be the kernel, a dongle, phone hardware, ... This can provide protection against local attackers.
  • Credential management: The credential manager can store and automatically supply the credentials if allowed by the user.
  • It may be possible to do a tiered system where the user can (temporary) provide the credential manager a way to generate proofs without storing master credentials.
  • Regarding phishing: The browser could tie the authentication to a specific SSL certificate. Alternatively, the web application can provide a proof of its identity to the browser as part of the authentication request by using the same type of algorithm (zero knowledge proof) in the other direction.
    Obviously it will be a long road to get this implemented from end to end. But it seems like a good moment to start such an effort.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants