- From: Brian Smith <brian@briansmith.org>
- Date: Thu, 31 Jul 2014 09:37:52 -0700
- To: Jacob S Hoffman-Andrews <jsha@eff.org>
- Cc: Mike West <mkwst@google.com>, Webapps WG <public-webapps@w3.org>
On Thu, Jul 31, 2014 at 8:19 AM, Jacob S Hoffman-Andrews <jsha@eff.org> wrote: > I'd say there are approximately three styles for login form submission: > A) No JS. A <form> with some <input type=text>'s that gets submitted when > you click an <input type=submit>. > B) Some JS. A <form> that gets submitted by JS calling form.submit(). > C) All JS. A set of <inputs> 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
Received on Thursday, 31 July 2014 16:38:21 UTC