Re: Proposal for a credential management API.
On Mon, Aug 18, 2014 at 7:07 PM, Hill, Brad wrote: > I think the broader goals Jonas has articulated probably belong in their > own group, perhaps chartered along with some of what comes out of the > upcoming Web Crypto Next Steps workshop. > I'm certainly interested in seeing what comes out of that workshop, and I'm equally curious about FIDO in general. Ideally, then, without being too optimistic, I'd like to see passwords > replaced entirely by better technology rather than continuing to kludge > upon them. They're still a fundamentally broken technology in many > important respects even with better management tools. > What's a timeframe in which you might reasonably expect that to happen? I suspect it's not "months" or "next year". We're having a hard enough time getting folks onto SSL, which is a much more basic requirement. I, personally, don't honestly expect passwords to be widely replaced in the near future, especially given how central they are to identity on today's web. Given the investment in password-based authentication systems, and the lethargic pace at which things like this tend to move, I think the use cases spelled out in my proposal remain quite relevant to today's web, and tomorrow's web. Hopefully they're less relevant to web 3.0, but that's a ways off. :) > Also, we should be careful in decomposing our targets here. Federation is > a different layer than replacing passwords or password management. There > are already a number of standards in that area which could be given > "native" support in a browser without having to re-invent the wheel. (e.g. > SAML2, WS-Federation, OpenID Connect / OAuth2, etc.) > I agree with this division. However, I'm hopeful that the strawman I've proposed is flexible enough to support a number of potential forms of credentials. It currently defines "local" and "federated" credentials broadly, and vaguely. In spirit, at least, it's following Mozilla's position paper's call for "a box implementations can go in", and is extensible by design. -- Mike West Google+: https://mkw.st/+, Twitter: @mikewest, Cell: +49 162 10 255 91 Google Germany GmbH, Dienerstrasse 12, 80331 München, Germany Registergericht und -nummer: Hamburg, HRB 86891 Sitz der Gesellschaft: Hamburg Geschäftsführer: Graham Law, Christine Elizabeth Flores (Sorry; I'm legally required to add this exciting detail to emails. Bleh.)
Re: Proposal for a credential management API.
I think the broader goals Jonas has articulated probably belong in their own group, perhaps chartered along with some of what comes out of the upcoming Web Crypto Next Steps workshop. http://www.w3.org/2012/webcrypto/webcrypto-next-workshop/papers.html I'll say by way of indicating possible conflict-of-interest that the FIDO Alliance is also working on parts of this problem space (https://fidoalliance.org) but is focusing more specifically on enabling strong authentication without passwords. We (FIDO) are presenting a paper at the workshop. Ideally, then, without being too optimistic, I'd like to see passwords replaced entirely by better technology rather than continuing to kludge upon them. They're still a fundamentally broken technology in many important respects even with better management tools. Also, we should be careful in decomposing our targets here. Federation is a different layer than replacing passwords or password management. There are already a number of standards in that area which could be given "native" support in a browser without having to re-invent the wheel. (e.g. SAML2, WS-Federation, OpenID Connect / OAuth2, etc.) -Brad On Aug 18, 2014, at 4:45 AM, Mike West wrote: > On Tue, Aug 12, 2014 at 10:19 PM, Jonas Sicking wrote: > > One- or two-click sign _up_, on the other hand, will likely be more > > difficult given the complexities of authorization (scopes, etc). > > I'm not sure what you count as sign-up? Today, if I visit a new > website that I've never visited before, I can log in to that website > in two clicks using identity providers as facebook/twitter/google. I > don't think anything more than that is going get the support we need. > > You're right. I was thinking about username/password flows for sign-up, which > can be significantly more complex than IDP's general "pick an IDP, then grant > access" flows. > > I'd like to support both, for what it's worth. > > -mike > > -- > Mike West > Google+: https://mkw.st/+, Twitter: @mikewest, Cell: +49 162 10 255 91 > > Google Germany GmbH, Dienerstrasse 12, 80331 München, Germany > Registergericht und -nummer: Hamburg, HRB 86891 > Sitz der Gesellschaft: Hamburg > Geschäftsführer: Graham Law, Christine Elizabeth Flores > (Sorry; I'm legally required to add this exciting detail to emails. Bleh.) >
Re: Proposal for a credential management API.
On Tue, Aug 12, 2014 at 10:19 PM, Jonas Sicking wrote: > > One- or two-click sign _up_, on the other hand, will likely be more > > difficult given the complexities of authorization (scopes, etc). > > I'm not sure what you count as sign-up? Today, if I visit a new > website that I've never visited before, I can log in to that website > in two clicks using identity providers as facebook/twitter/google. I > don't think anything more than that is going get the support we need. > You're right. I was thinking about username/password flows for sign-up, which can be significantly more complex than IDP's general "pick an IDP, then grant access" flows. I'd like to support both, for what it's worth. -mike -- Mike West Google+: https://mkw.st/+, Twitter: @mikewest, Cell: +49 162 10 255 91 Google Germany GmbH, Dienerstrasse 12, 80331 München, Germany Registergericht und -nummer: Hamburg, HRB 86891 Sitz der Gesellschaft: Hamburg Geschäftsführer: Graham Law, Christine Elizabeth Flores (Sorry; I'm legally required to add this exciting detail to emails. Bleh.)
Re: Proposal for a credential management API.
On Tue, Aug 12, 2014 at 9:33 AM, Mike West wrote: >> * Enable a login flow which is less "jarring" UX-wise than today's >> redirects. >> * Don't increase the number of clicks needed to log in. Today two >> clicks are usually enough, we shouldn't be worse than that since then >> websites won't adopt it and user's won't like it. > > One-click sign-in (with a zero-click, "Keep me logged in" option) is a very > reasonable goal, and one that I think is achievable. > > One- or two-click sign _up_, on the other hand, will likely be more > difficult given the complexities of authorization (scopes, etc). I'm not sure what you count as sign-up? Today, if I visit a new website that I've never visited before, I can log in to that website in two clicks using identity providers as facebook/twitter/google. I don't think anything more than that is going get the support we need. / Jonas
Re: Proposal for a credential management API.
Hi Jonas, thanks for this feedback! On Tue, Aug 12, 2014 at 11:51 AM, Jonas Sicking wrote: > I'm very interested in improving the login experience on websites. In > particular I'd like to create a better flow when federated logins are > used, with at least the following goals: > I think these are laudable goals. Taken together, I worry that we'll be trying to boil the ocean, but I certainly agree with the general sentiment and direction. > * Enable the user to manage their accounts in browser chrome rather > than have to go to specific websites to log out. > This will almost certainly require cooperation from both the RP and IDP side of the equation. Given that, I worry that the browser will be promising things that it can't actually guarantee if it pops up a "Sign out" button. > * Enable a login flow which is less "jarring" UX-wise than today's > redirects. > * Don't increase the number of clicks needed to log in. Today two > clicks are usually enough, we shouldn't be worse than that since then > websites won't adopt it and user's won't like it. > One-click sign-in (with a zero-click, "Keep me logged in" option) is a very reasonable goal, and one that I think is achievable. One- or two-click sign _up_, on the other hand, will likely be more difficult given the complexities of authorization (scopes, etc). > * Make it easier for websites to support multiple federated login > providers by ensuring that they all use a common API. I.e. adding > support for more login providers shouldn't need to require running > code specific to that provider. > I worry about http://xkcd.com/927/. To pick on an easy target, there are already several dialects of OAuth2 that IDPs provide SDKs to speak. Moreover, it's not clear that any IDP actually considers this a bug. Easy migration between IDPs is absolutely a benefit to the user, as is easy integration with new IDPs for authors. It's something that we should attempt to provide, but it is a large undertaking. > * Enable the UA to track which login providers that the user has > accounts with so that the UA can render UI which only displays > providers that are relevant to the user. > The strawman I posted does this by using the password manager that's already in browsers. If you've saved Funky Federation credentials, then the UA can be reasonably sure that it should present you with that Funky option when a website claims to support it. This seems like the simplest possible way of getting the information, without requiring IDP support. > All of these goals are likely not required. But I definitely want to > make sure that whatever we build is attractive enough to users, > webdevelopers and federated-login-providers that it actually gets > used. > I agree that this is paramount. -- Mike West Google+: https://mkw.st/+, Twitter: @mikewest, Cell: +49 162 10 255 91 Google Germany GmbH, Dienerstrasse 12, 80331 München, Germany Registergericht und -nummer: Hamburg, HRB 86891 Sitz der Gesellschaft: Hamburg Geschäftsführer: Graham Law, Christine Elizabeth Flores (Sorry; I'm legally required to add this exciting detail to emails. Bleh.)
Re: Proposal for a credential management API.
Hi Mike, I'm very interested in improving the login experience on websites. In particular I'd like to create a better flow when federated logins are used, with at least the following goals: * Make it easier for websites to use federated login as to discourage passwords. * Ensure that the designed solution has support from most commonly used federated login providers. * Enable the user to manage their accounts in browser chrome rather than have to go to specific websites to log out. * Enable a login flow which is less "jarring" UX-wise than today's redirects. * Don't increase the number of clicks needed to log in. Today two clicks are usually enough, we shouldn't be worse than that since then websites won't adopt it and user's won't like it. * Make it easier for websites to support multiple federated login providers by ensuring that they all use a common API. I.e. adding support for more login providers shouldn't need to require running code specific to that provider. * Enable the UA to track which login providers that the user has accounts with so that the UA can render UI which only displays providers that are relevant to the user. * Enable the user to have multiple accounts with the same provider for providers that allow this. All of these goals are likely not required. But I definitely want to make sure that whatever we build is attractive enough to users, webdevelopers and federated-login-providers that it actually gets used. / Jonas On Thu, Jul 31, 2014 at 12:48 AM, Mike West wrote: > TL;DR: Strawman spec and usecases at > https://github.com/mikewest/credentialmanagement > > # Use Cases > > User agents' password managers are a fragile and proprietary hodgepodge of > heuristics meant to detect and fill sign-in forms, password change forms, > etc. > We can do significantly better if we invite websites' explicit cooperation: > > * Federated identity providers are nigh undetectable; I don't know of any > password managers that try to help users remember that they signed into > Stack Overflow with Twitter, not Google. > > * Signing in without an explicit form submission (via XHR, WebSockets(!), > etc) is good for user experience, but difficult to reliably detect. > > * Password change forms are less well-supported than they could be. > > * Users are on their own when creating new accounts, faced either with a > list of identity providers they've mostly never heard of, or with the > challenge of coming up with a clever new password. > > More background and exploration of native equivalents at > http://projects.mikewest.org/credentialmanagement/usecases/. > > # Workarounds > > HTML defines a number of `autocomplete` attributes which help explain > fields' > purpose to user agents. These make the common case of form submission more > reliably detectable, but are less helpful for XHR-based sign-in, and don't > address federated identity providers at all. > > # Proposal: > > The API I'm outlining here is intentionally small and simple: it does not > attempt to solve the general authentication problem in itself, but instead > provides an interface to user agents' existing password managers. That > functionality is valuable _now_, without significant effort on the part of > either browser vendors or website authors. > > The API quite intentionally winks suggestively in the direction of an > authentication API that would, for instance, do an OAuth dance on behalf of > an > application, but that's not the immediate goal. > > ``` > [NoInterfaceObject] > interface Credential { > readonly attribute DOMString id; > readonly attribute DOMString name; > readonly attribute DOMString avatarURL; > }; > > [Constructor(DOMString id, DOMString password, DOMString name, DOMString > avatarURL)] > interface LocalCredential : Credential { > readonly attribute DOMString password; > }; > > [Constructor(DOMString id, DOMString federation, DOMString name, DOMString > avatarURL)] > interface FederatedCredential : Credential { > readonly attribute DOMString federation; > }; > > partial interface Navigator { > readonly attribute CredentialsContainer credentials; > }; > > interface CredentialsContainer { > Promise request(optional CredentialRequestOptions options); > Promise notifySignedIn(optional Credential credential); > Promise notifyFailedSignIn(optional Credential credential); > Promise notifySignedOut(); > readonly attribute PendingCredential? pending; > }; > ``` > > A more detailed specification is up at > http://projects.mikewest.org/credentialmanagement/spec/. > > # Example: > > ``` > navigator.credentials.request({ > 'federations': [ 'https://federated-identity-provider.com/' ] > }).then(function(credential) { > if (!credential) { > // The user had no credentials, or elected not to provide one to this > site. > // Fall back to an existing login form. > } > > var xhr = new XMLHttpRequest(); > xhr.open("POST", "https://example.com/loginEndpoint";); > var formData = new FormData()
Re: Write-only form fields (was Re: Proposal for a credential management API.)
Thanks Jacob! On Fri, Aug 1, 2014 at 6:48 PM, Jacob S Hoffman-Andrews wrote: > I think the CSP directive is unnecessary and makes things more fragile. The > 'protect this credential from XSS' attribute should be a property of a > stored credential, not a web site. If the site has the correct CSP headers > on 99% of its website, but then for some reason doesn't have them on one > page, that page is a potential vector to expose the credential. 1. Nothing in the 'writeonly' document prevents UAs from using some sort of heuristic to determine when to fill forms. We already look at things like the form action, there's no reason we couldn't also look at the page-level policy, or field-level attributes. Tagging the credential as 'writeonly' is certainly compatible with this approach. 2. We need CSP anyway in order to specify where forms may permissibly be submitted. Using it as a mechanism for setting a writeonly policy seems like a reasonable extension. > I think making input fields write-only is more powerful than we strictly > need. When a user is manually entering a password, it's okay for the page to > be able to read the value they are typing in. If the page has been modified > by an attacker at this point, it's too late. It seems like we could prevent this attack if we stop firing events on 'writeonly' fields. At best, that would prevent reading the value. At worst, that would make the attacker's job harder (she'd have to layer an invisible field over the password field and do magic to get the value out of the one and into the other). > What we want is a mechanism to specify 'once this value is stored in a > password manager*, protect it from future JS on this page.' That's why I > feel like it's relevant to define credential management APIs for the web. > > *or credit card autofiller. 1. How do we retroactively apply this policy to users' existing credentials? 'writeonly' is a nice, drop-in solution that works for existing credentials as well as new credentials. 2. I'd prefer not to rely on multiple subsystems' understanding of the "protect from JS" concept. In Chrome, at least, credit cards and passwords are in separate databases, and filled via different code paths. I suspect that doing the work once at the DOM-level would be less error-prone. > The write-only spec fully breaks XHR form submission (style C in my earlier > mail). As Brian pointed out, the placeholder approach can be made to work > with XHR if you're willing to do a little extra inspection of arbitrary > XHRs. This approach breaks XHR-based systems which read the data directly from the form field. It doesn't necessarily break an API-driven mechanism. > Also, as you pointed out, write-only breaks client-side validation. > Client-side validation is very broadly used for password strength meters > during signup and change password. I think interfering with strength meters > would make it a lot harder for implementers to adopt the spec. Would we need strength meters for sign-in forms? We'd really only need those for sign-up forms when users are creating an account, right? If we can find a reasonable way of distinguishing the two, we can address this use case. For example, if we set a CSP which includes `autocomplete="current-password"`, but excludes `autocomplete="new-password"` (and we assert that browsers are updated to exclude 'new-password' from autofill), we'd get the advantages of a blanket page-level policy, while allowing developers to help users create strong passwords. >> I'm curious about the use cases for protecting the password from the >> webserver. >> > One common use case for client-side crypto is removing systems from scope in > PCI (payment card industry) compliance. There's a set of standards related > to the handling of credit/debit cards that involve auditing all systems that > have card data. There are third-party services that offer compliance by > having you encrypt card data in JS and pass it, encrypted, through all your > non-compliant systems and into their secure vault where it is decrypted. Interesting. The proposal I've made doesn't support this use case. How common do you believe it is? If we need to support it, then blocking JS-level access to the form data will be difficult. -mike
Re: Write-only form fields (was Re: Proposal for a credential management API.)
Your proposal decouples spec from implementation more than the placeholder approach does, which is good. I think the CSP directive is unnecessary and makes things more fragile. The 'protect this credential from XSS' attribute should be a property of a stored credential, not a web site. If the site has the correct CSP headers on 99% of its website, but then for some reason doesn't have them on one page, that page is a potential vector to expose the credential. I think making input fields write-only is more powerful than we strictly need. When a user is manually entering a password, it's okay for the page to be able to read the value they are typing in. If the page has been modified by an attacker at this point, it's too late. What we want is a mechanism to specify 'once this value is stored in a password manager*, protect it from future JS on this page.' That's why I feel like it's relevant to define credential management APIs for the web. *or credit card autofiller. The write-only spec fully breaks XHR form submission (style C in my earlier mail). As Brian pointed out, the placeholder approach can be made to work with XHR if you're willing to do a little extra inspection of arbitrary XHRs. Also, as you pointed out, write-only breaks client-side validation. Client-side validation is very broadly used for password strength meters during signup and change password. I think interfering with strength meters would make it a lot harder for implementers to adopt the spec. I'm curious about the use cases for protecting the password from the webserver. One common use case for client-side crypto is removing systems from scope in PCI (payment card industry) compliance. There's a set of standards related to the handling of credit/debit cards that involve auditing all systems that have card data. There are third-party services that offer compliance by having you encrypt card data in JS and pass it, encrypted, through all your non-compliant systems and into their secure vault where it is decrypted.
Re: Write-only form fields (was Re: Proposal for a credential management API.)
On Fri, Aug 1, 2014 at 3:31 PM, Brian Smith wrote: > There is some tension here between making things password-specific and > simple vs. making them general and harder to understand. Defining this > as a mechanism to protect only passwords keeps it simple. But, it > seems wrong to have a way to protect passwords but not credit card > numbers and social security numbers and other very sensitive input > fields that don't use . I hadn't considered autofilled credit cards; that's a reasonable use case. We could address credit cards by turning the CSP directive into a list of autocomplete attribute values: `form-readonly cc-number cc-csc ... current-password new-password`. That seems like it would address the credential use case, while leaving flexibility for future field types that developers might care about giving extra protection. That said, it gets quite verbose. If we go this route, perhaps we could come up with a chunk of those types we'd expect developers to want to protect, and give them a special keyword expression: `form-readonly 'the-usual-stuff'`. > I am not sure that looking only at POSTs is sufficient. I don't think we should encourage GET-based submission of valuable information. > websites put login forms on every page (whether they should or not). If we filled a form on every page, but the user never logged in, there would indeed be a (marginal?) performance impact if we had to examine every POST a website made. That feels like an edgy enough case that we don't have to worry too much about it, but I don't have any numbers to back that up. > But, I agree that it would be better to avoid the need for the > attribute if we can. The less work we make the website do to get some security benefit, the better. > I suspect some websites will want to disable some aspects of their > form validation code if they are dealing with placeholders instead of > the real values, especially if the mechanism is extended to things > such as social security numbers and credit card numbers. If the field is write-only, they won't be able to do client-side validation. That's a necessary consequence of keeping the password out of the renderer, and out of reach of JavaScript. I agree that this is more problematic for SSN or CC fields than for passwords, but I don't see an alternative that would keep the renderer in the dark about the actual value. If they use the credential management API to get credentials, they'll only be getting credentials the user saved. Presumably the user wouldn't save credentials that weren't valid for the site. >> I'm pretty happy to break that use case, given that the credential API I've >> proposed is locked to secure origins. There's no advantage to using >> WebCrypto to doubly encrypt the password in this context, and I don't think >> it's something we should encourage. > > I think it is fine to say that this would be mutually-exclusive with > WebCrypto-based approaches to encrypting passwords in the short term. > However, I think it is too early in the history of WebCrypto to say > that there's advantage to encrypting passwords (or other sensitive > information like credit card numbers) in a way that protects them from > the from the web server. I think it is likely that some way of > composing WebCrypto and this mechanism will be necessary, eventually. I'm curious about the use cases for protecting the password from the webserver. I've had some conversations with Sigbjørn Vik about returning hashed passwords rather than "real" passwords, which might be going along the lines you're thinking. That is, the site would provide hash function and a server nonce when requesting credentials, and the UA would return a client nonce and a LocalCredential whose password value was `hash(password + server nonce + client nonce)`. I think that's worth exploring, but it's tough to do well without requiring the site to hold passwords in plaintext. Is that the kind of use case you're considering? -- Mike West Google+: https://mkw.st/+, Twitter: @mikewest, Cell: +49 162 10 255 91 Google Germany GmbH, Dienerstrasse 12, 80331 München, Germany Registergericht und -nummer: Hamburg, HRB 86891 Sitz der Gesellschaft: Hamburg Geschäftsführer: Graham Law, Christine Elizabeth Flores (Sorry; I'm legally required to add this exciting detail to emails. Bleh.)
Re: Write-only form fields (was Re: Proposal for a credential management API.)
On Fri, Aug 1, 2014 at 5:37 AM, Mike West wrote: > On Thu, Jul 31, 2014 at 6:37 PM, Brian Smith wrote: >> particular, if we are worried about XSS stealing passwords then we >> have to consider the possibility that XSS has inserted a form without >> any httponly attributes being used, right? > > Correct. I think we'd also want a new CSP directive which toggles write-only > status for all password fields on a given page: how about > http://projects.mikewest.org/credentialmanagement/writeonly/#credentials-directive? There is some tension here between making things password-specific and simple vs. making them general and harder to understand. Defining this as a mechanism to protect only passwords keeps it simple. But, it seems wrong to have a way to protect passwords but not credit card numbers and social security numbers and other very sensitive input fields that don't use . >> This would work with (C) too, would it not? It may be a good idea to >> add an attribute to XHR to trigger such replacement, so that the >> browser doesn't have to attempt substitution for every HTTP request. > > I think we'd be able to get away with relying on magical UA behavior: if the > browser process hands a nonce to a renderer, it can set a flag, and then > look at POSTs generated by the page. As soon as one POST contains the nonce, > clear the flag. My suspicion is that most login pages don't do much POSTing, > so the overhead would be trivial. I am not sure that looking only at POSTs is sufficient. Also, some websites put login forms on every page (whether they should or not). But, I agree that it would be better to avoid the need for the attribute if we can. > I'd prefer that approach, because I don't think we want to expose the actual > mechanics to the web. The website shouldn't need to care about whether or > not the password it's received is the "real" password or not. I suspect some websites will want to disable some aspects of their form validation code if they are dealing with placeholders instead of the real values, especially if the mechanism is extended to things such as social security numbers and credit card numbers. >> Based on a quick read of Mike's proposal, this would require Mike's >> proposed API to change to pass around tokens that represent passwords, >> instead of the password values themselves. This would add >> complication, but it would be useful. > > This approach adds complication to the UA's implementation, but shouldn't > add complexity to the site consuming the API. > >> This would probably not interact well with use of the WebCrypto API to >> encrypt the contents of input fields (passwords, credit card numbers, >> etc.) before submission. > > I'm pretty happy to break that use case, given that the credential API I've > proposed is locked to secure origins. There's no advantage to using > WebCrypto to doubly encrypt the password in this context, and I don't think > it's something we should encourage. I think it is fine to say that this would be mutually-exclusive with WebCrypto-based approaches to encrypting passwords in the short term. However, I think it is too early in the history of WebCrypto to say that there's advantage to encrypting passwords (or other sensitive information like credit card numbers) in a way that protects them from the from the web server. I think it is likely that some way of composing WebCrypto and this mechanism will be necessary, eventually. Cheers, Brian
Re: Proposal for a credential management API.
Hi Mike, On 31/07/2014 09:48 , Mike West wrote: It's not clear to me that WebApps is the right venue from a process perspective, but this is almost certainly the right group of people to evaluate the proposal. Thanks in advance for your feedback, suggestions, and time. :) As you know I think that a solution in this space is absolutely needed and I like your approach, I think it's on to the right set of use cases. There are some paper cuts with your proposal but nothing I've seen that can't be ironed out. Concerning the process part, I'd like to only worry about that as much as needed, which shouldn't be a lot. We can work something out and come back to you with a solution to make this happen. -- Robin Berjon - http://berjon.com/ - @robinberjon
Write-only form fields (was Re: Proposal for a credential management API.)
Forking this out into a separate thread, as I think it's a great idea, but tangential to the original proposal. :) TL;DR: I put together a strawman based on these suggestions which defines a 'writeonly' attribute on HTMLInputElement: http://projects.mikewest.org/credentialmanagement/writeonly/, WDYT? On Thu, Jul 31, 2014 at 6:37 PM, Brian Smith wrote: > And/or the password form could be annotated with an attribute that > indicates for which domain an XHR should be allowed to submit the > password to. And/or, you could have a submit-password CSP directive to > indicate which domains passwords are allowed to be submitted to. We already have 'form-action', I think that serves the purpose suitably well: https://w3c.github.io/webappsec/specs/content-security-policy/#directive-form-action > particular, if we are worried about XSS stealing passwords then we > have to consider the possibility that XSS has inserted a form without > any httponly attributes being used, right? Correct. I think we'd also want a new CSP directive which toggles write-only status for all password fields on a given page: how about http://projects.mikewest.org/credentialmanagement/writeonly/#credentials-directive ? > I was thinking the placeholder would be a base64url-encoded > cryptographically-random nonce of sufficient length, so that the > browser can replace the placeholders within arbitrary HTTP requests, > regardless of (most) use of JS to mangle forms before submitting them, > and without worrying about replacing the wrong part. I agree, but I don't think we need to specify this normatively. User agents will know what they can easily replace and what they can't, if they choose to go down a nonce route. > This would work with (C) too, would it not? It may be a good idea to > add an attribute to XHR to trigger such replacement, so that the > browser doesn't have to attempt substitution for every HTTP request. I think we'd be able to get away with relying on magical UA behavior: if the browser process hands a nonce to a renderer, it can set a flag, and then look at POSTs generated by the page. As soon as one POST contains the nonce, clear the flag. My suspicion is that most login pages don't do much POSTing, so the overhead would be trivial. I'd prefer that approach, because I don't think we want to expose the actual mechanics to the web. The website shouldn't need to care about whether or not the password it's received is the "real" password or not. > Based on a quick read of Mike's proposal, this would require Mike's > proposed API to change to pass around tokens that represent passwords, > instead of the password values themselves. This would add > complication, but it would be useful. This approach adds complication to the UA's implementation, but shouldn't add complexity to the site consuming the API. > This would probably not interact well with use of the WebCrypto API to > encrypt the contents of input fields (passwords, credit card numbers, > etc.) before submission. I'm pretty happy to break that use case, given that the credential API I've proposed is locked to secure origins. There's no advantage to using WebCrypto to doubly encrypt the password in this context, and I don't think it's something we should encourage. Thanks! -- Mike West Google+: https://mkw.st/+, Twitter: @mikewest, Cell: +49 162 10 255 91 Google Germany GmbH, Dienerstrasse 12, 80331 München, Germany Registergericht und -nummer: Hamburg, HRB 86891 Sitz der Gesellschaft: Hamburg Geschäftsführer: Graham Law, Christine Elizabeth Flores (Sorry; I'm legally required to add this exciting detail to emails. Bleh.)
Re: Proposal for a credential management API.
On Thu, Jul 31, 2014 at 6:40 PM, Brian Smith wrote: > On Thu, Jul 31, 2014 at 9:37 AM, Brian Smith wrote: >> Web browsers with sandboxed child processes have the networking logic >> in the more-privileged parent process. The purpose of sandboxing is to >> protect against exploits in the child process. It would be useful for >> the process/privilege separation of sandboxing to be able to protect >> the values of passwords--even if it can't always protect the *use* of >> the passwords--even in the event of a compromised child process. > > By the way, I don't know if any browsers do this, but AFAICT HttpOnly > cookies can be protected by such process separation in the same way, > and we should ensure that ServiceWorkers is defined and implemented in > a way that allows for such protection to (continue to) work. Cookies (the non-HttpOnly kind) remain only exposed through document.cookie. Service workers, like XMLHttpRequest, have no access to cookies (including the non-HttpOnly kind) at all. -- http://annevankesteren.nl/
Re: Proposal for a credential management API.
On Thu, Jul 31, 2014 at 9:37 AM, Brian Smith wrote: > Web browsers with sandboxed child processes have the networking logic > in the more-privileged parent process. The purpose of sandboxing is to > protect against exploits in the child process. It would be useful for > the process/privilege separation of sandboxing to be able to protect > the values of passwords--even if it can't always protect the *use* of > the passwords--even in the event of a compromised child process. By the way, I don't know if any browsers do this, but AFAICT HttpOnly cookies can be protected by such process separation in the same way, and we should ensure that ServiceWorkers is defined and implemented in a way that allows for such protection to (continue to) work. Cheers, Brian
Re: Proposal for a credential management API.
On Thu, Jul 31, 2014 at 8:19 AM, Jacob S Hoffman-Andrews wrote: > I'd say there are approximately three styles for login form submission: > A) No JS. A with some 's that gets submitted when > you click an . > B) Some JS. A that gets submitted by JS calling form.submit(). > C) All JS. A set of whose contents are extracted by JS and POST'ed > via XHR to the server. > > Clearly we can't make C safe against XSS. But I think a lot of web sites > currently use A or B, or would be willing to use them in exchange for better > security. I think we can make C work too. > Here's a rough idea: Define a new attribute 'httponly' for input elements. And/or the password form could be annotated with an attribute that indicates for which domain an XHR should be allowed to submit the password to. And/or, you could have a submit-password CSP directive to indicate which domains passwords are allowed to be submitted to. In particular, if we are worried about XSS stealing passwords then we have to consider the possibility that XSS has inserted a form without any httponly attributes being used, right? > When a text input has httponly=true and the password manager saves the input > value as a PendingCredential or a Credential, the password manager also > stores an attribute httpOnly=true on the Credential. When the password > manager autofills forms using a Credential with httpOnly=true, it should > fill a placeholder value (possibly a numeric identifier for the Credential). I was thinking the placeholder would be a base64url-encoded cryptographically-random nonce of sufficient length, so that the browser can replace the placeholders within arbitrary HTTP requests, regardless of (most) use of JS to mangle forms before submitting them, and without worrying about replacing the wrong part. > When a form is submitted, the password manager should intercept the HTTP > request and replace the placeholder value with the contents of the > Credential. This would work with (C) too, would it not? It may be a good idea to add an attribute to XHR to trigger such replacement, so that the browser doesn't have to attempt substitution for every HTTP request. Web browsers with sandboxed child processes have the networking logic in the more-privileged parent process. The purpose of sandboxing is to protect against exploits in the child process. It would be useful for the process/privilege separation of sandboxing to be able to protect the values of passwords--even if it can't always protect the *use* of the passwords--even in the event of a compromised child process. The placeholder technique described by Jacob would facilitate such protection by giving the browser the ability to withhold passwords from the child (renderer) processes. Based on a quick read of Mike's proposal, this would require Mike's proposed API to change to pass around tokens that represent passwords, instead of the password values themselves. This would add complication, but it would be useful. This would probably not interact well with use of the WebCrypto API to encrypt the contents of input fields (passwords, credit card numbers, etc.) before submission. However, it seems reasonable to think that we could provide some way to integrate both things. One way would be to define a new API for declarative crypto operations, that allow the browser to do the substitution and then the crypto without the application's JS logic ever seeing it. Another way would be to provide a mechanism for isolating JS code from the DOM (possible reusing the worker infrastructure) so that some small part of the page's JS code can do the necessary transformations given the cleartext passwords, without leaking them; this seems hard though. Also note how this is pretty at odds with the idea (as I vaguely understand it) that ServiceWorkers should be able to do anything that the browser could do, unless the placeholder replacement was done for outgoing requests made by ServiceWorkers too. But, I think the protection of passwords and similar secrets is worthwhile enough to make exceptions and/or do extra work to resolve this conflict. BTW, Jacob's placeholder idea is similar to the ideas in: https://bugzilla.mozilla.org/show_bug.cgi?id=653132 and https://bugzilla.mozilla.org/show_bug.cgi?id=759860#c2 AFAICT, many "security" people at Mozilla thought it was a good idea, but nobody has tried to implement it in Firefox yet. I also think it is a good idea for some browser to try it out. Cheers, Brian
Re: Proposal for a credential management API.
I like the idea of standardizing some of the interactions between password managers and web sites. I think we should strongly consider ways to integrate XSS mitigation. Hopefully before too long most people will be using a password manager. With most password managers, if there is a transient XSS on example.com, an attacker can use that XSS to trick the password manager into autofilling the password for example.com. This means, even though the XSS exposure might be temporary, the attackers can steal a large number of passwords, extending the attack window indefinitely. Some other reasons that XSS + password stealing is worse than plain XSS: 1) Passwords are often reused across web sites, so damage from password stealing spreads fast. 2) When the XSS is fully client-side, it is impossible to figure out which users had their passwords stolen. There is no way to reset their passwords and they may remain compromised indefinitely. 3) Sites often require re-entering passwords for privileged actions like changing email address or adding an SSH key. Adding password stealing to an XSS acts like privilege escalation, allowing actions that aren't possible with a plain XSS. Cookies have a very similar problem. If an XSS can grab the user's authentication cookies, the attacker can prolong their attack even after the XSS hole is closed. Microsoft addressed the problem in 2002 by adding the 'HttpOnly' flag for cookies in MSIE 6 SP 1. All browsers implement it now, to great effectiveness. At a past job, I fixed XSS for a top ten web site, and I can testify that it was incredibly valuable to know that attackers were not stealing our authentication cookies, because we set the HttpOnly flag.. There's no HttpOnly equivalent for password forms, but that's largely because password storage by the browser has never been specified. As long as we're trying to specify parts of that storage, I think we should strive for HttpOnly passwords. It's challenging because there are many different login techniques, but I think we can make it happen if web sites opt in. I'd say there are approximately three styles for login form submission: A) No JS. A with some 's that gets submitted when you click an . B) Some JS. A that gets submitted by JS calling form.submit(). C) All JS. A set of whose contents are extracted by JS and POST'ed via XHR to the server. Clearly we can't make C safe against XSS. But I think a lot of web sites currently use A or B, or would be willing to use them in exchange for better security. Here's a rough idea: Define a new attribute 'httponly' for input elements. When a text input has httponly=true and the password manager saves the input value as a PendingCredential or a Credential, the password manager also stores an attribute httpOnly=true on the Credential. When the password manager autofills forms using a Credential with httpOnly=true, it should fill a placeholder value (possibly a numeric identifier for the Credential). When a form is submitted, the password manager should intercept the HTTP request and replace the placeholder value with the contents of the Credential. Note that this proposal doesn't break password strength meters implemented in JS, because it only addresses subsequent autofills of credentials. The first time a password is entered, e.g. during signup or change password, it is still fully accessible to JS. Thanks, Jacob
Proposal for a credential management API.
TL;DR: Strawman spec and usecases at https://github.com/mikewest/credentialmanagement # Use Cases User agents' password managers are a fragile and proprietary hodgepodge of heuristics meant to detect and fill sign-in forms, password change forms, etc. We can do significantly better if we invite websites' explicit cooperation: * Federated identity providers are nigh undetectable; I don't know of any password managers that try to help users remember that they signed into Stack Overflow with Twitter, not Google. * Signing in without an explicit form submission (via XHR, WebSockets(!), etc) is good for user experience, but difficult to reliably detect. * Password change forms are less well-supported than they could be. * Users are on their own when creating new accounts, faced either with a list of identity providers they've mostly never heard of, or with the challenge of coming up with a clever new password. More background and exploration of native equivalents at http://projects.mikewest.org/credentialmanagement/usecases/. # Workarounds HTML defines a number of `autocomplete` attributes which help explain fields' purpose to user agents. These make the common case of form submission more reliably detectable, but are less helpful for XHR-based sign-in, and don't address federated identity providers at all. # Proposal: The API I'm outlining here is intentionally small and simple: it does not attempt to solve the general authentication problem in itself, but instead provides an interface to user agents' existing password managers. That functionality is valuable _now_, without significant effort on the part of either browser vendors or website authors. The API quite intentionally winks suggestively in the direction of an authentication API that would, for instance, do an OAuth dance on behalf of an application, but that's not the immediate goal. ``` [NoInterfaceObject] interface Credential { readonly attribute DOMString id; readonly attribute DOMString name; readonly attribute DOMString avatarURL; }; [Constructor(DOMString id, DOMString password, DOMString name, DOMString avatarURL)] interface LocalCredential : Credential { readonly attribute DOMString password; }; [Constructor(DOMString id, DOMString federation, DOMString name, DOMString avatarURL)] interface FederatedCredential : Credential { readonly attribute DOMString federation; }; partial interface Navigator { readonly attribute CredentialsContainer credentials; }; interface CredentialsContainer { Promise request(optional CredentialRequestOptions options); Promise notifySignedIn(optional Credential credential); Promise notifyFailedSignIn(optional Credential credential); Promise notifySignedOut(); readonly attribute PendingCredential? pending; }; ``` A more detailed specification is up at http://projects.mikewest.org/credentialmanagement/spec/. # Example: ``` navigator.credentials.request({ 'federations': [ 'https://federated-identity-provider.com/' ] }).then(function(credential) { if (!credential) { // The user had no credentials, or elected not to provide one to this site. // Fall back to an existing login form. } var xhr = new XMLHttpRequest(); xhr.open("POST", "https://example.com/loginEndpoint";); var formData = new FormData(); formData.append("username", credential.id); formData.append("password", credential.password); xhr.onreadystatechange = function () { if (this.readyState != this.DONE) return; var loginSucceeded = // Process response: if login succeeded, yay! If not, boo!; if (loginSucceeded) { navigator.credentials.notifySignedIn(credential); // Notify the user that signin succeeded! Do amazing, signed-in things! } else { navigator.credentials.notifyFailedSignIn(credential); // Notify the user that signin failed, and fall back to the usual experience. } }; xhr.send(formData); }); ``` More examples at http://projects.mikewest.org/credentialmanagement/spec/#introduction-examples . It's not clear to me that WebApps is the right venue from a process perspective, but this is almost certainly the right group of people to evaluate the proposal. Thanks in advance for your feedback, suggestions, and time. :) -mike -- Mike West Google+: https://mkw.st/+, Twitter: @mikewest, Cell: +49 162 10 255 91 Google Germany GmbH, Dienerstrasse 12, 80331 München, Germany Registergericht und -nummer: Hamburg, HRB 86891 Sitz der Gesellschaft: Hamburg Geschäftsführer: Graham Law, Christine Elizabeth Flores (Sorry; I'm legally required to add this exciting detail to emails. Bleh.)