- From: Michaela Merz <michaela.merz@rollofone.com>
- Date: Thu, 12 Sep 2019 12:20:50 -0500
- To: John Wilander <wilander@apple.com>
- Cc: Craig Francis <craig.francis@gmail.com>, "public-webappsec@w3.org" <public-webappsec@w3.org>
- Message-ID: <1b3e000e-910c-dd7b-860b-fb7c2433f853@rollofone.com>
Hi John: I certainly accept the fact - and I made that clear - that the browser should defend the user against malicious actions, and that includes unwanted tracking. I am not happy with blocking communications due to convenience concerns - e.g. autoplay. If users don't like blaring videos, they are free to never again visit the site. Convenience filtering is a slippery slope: Will we at some point see image blocking, because users may feel uncomfortable with certain depictions - or an automatic browser profanity filter? Once we start to accept the convenience factor as valid reasons to filter or prohibit certain elements - where will that end? But I am digressing. I don't see any reason for a browser to know whether or not a user is logged in. There is no real need for it to know. We have all the elements necessary to provide and maintain save and secure user contexts. I also don't see serious problems with storing a few mbyte of web-data for a few weeks. However - to address your concerns, I think it would be ok if the maximum lifetime of a cookie would be set to say .. 30 days to cover automatic storage deletion. Michaela > Hi Michaela! > >> On Sep 12, 2019, at 8:47 AM, Michaela Merz >> <michaela.merz@rollofone.com <mailto:michaela.merz@rollofone.com>> wrote: >> >> John & Craig - >> >> Thank you for your thoughts. Please excuse my poor choice of words - >> I understood the principle idea about the browser 'knowing' if a user >> is logged in - though I am not sure if an 'all knowing' browser is >> desirable. Additionally - only allowing methods that would require >> the browser or third parties 'remembering' the user name and/or >> password is IMHO a bad idea. >> > As mentioned in the explainer and pointed out by Craig, IsLoggedIn may > also cover cases where the user logs in manually, i.e. no password > manager and no WebAuthn. >> >> Though the paradigm has been softened lately (e.g. autoplay, >> Google's Media Engagement Index), I truly believe the browser should >> be nothing but an instrument through which a user is able to >> communicate with a web-site. >> > The browser is the user agent. Its main purpose is to be on the user’s > side, not on the website’s side. In the case of browsers with tracking > preventions, this means actively deleting website data on the user’s > behalf, blocking access to website data, or blocking whole resource > loads. I do not agree that the "browser should be nothing but an > instrument through which a user is able to communicate with a website” > and the WebKit engine is not such an instrument, as exemplified in our > Tracking Prevention Policy: https://webkit.org/tracking-prevention-policy/ >> >> Yes - it should try to identify clearly malicious intentions and >> shield the user from it, but it should not become an instrument that >> interferes with the web-sites codified intentions unless absolutely >> necessary. >> > “Absolutely necessary” may mean different things. But modern browsers > take active measures against what websites intend to do in many cases, > for instance for user experience (popup blocking, autoplay blocking), > security (mixed content blocking, “Not secure” labeling, Safe > Browsing, https auto upgrade), and tracking prevention (website data > deletion, website data blocking, content blocking). >> >> A browser 'controlled' ( for the lack of a better word ) login may >> very well become standard some day. It should never require ANY >> stored password, be it in the browser or federated. Not even thinking >> about the greed of (some) governments, what about using a friends >> computer to login into an account, public terminals and such? >> > Again, manual logins are covered by the explainer. > > Regards, John > >> On 9/12/19 8:16 AM, John Wilander wrote: >> >>> Hi Michaela and Craig! >>> >>> Thank you both for your comments. Craig is spot on in his reply. >>> >>> I’d like to address two additional things based on what you write, >>> Michaela: >>> >>> 1. “Making logins more secure.” While I’m all for making logins more >>> secure, IsLoggedIn isn’t really about that. It’s about the browser >>> *knowing* where the user is logged in and using that signal to help >>> them stay logged in on those sites while addressing the “logged in >>> by default” legacy problem for other sites. >>> >>> 2. “Nothing is ever transferred to or stored in the browser.” We >>> might be talking about different things here but the browser is >>> involved in all the login mechanisms that come to mind, and it does >>> store things. Authentication cookies are by far the most common >>> thing to store as part of a login. Is there something else you worry >>> about being stored? The IsLoggedIn bit itself? >>> >>> Regards, John >>> >>>> On Sep 12, 2019, at 4:57 AM, Craig Francis >>>> <craig.francis@gmail.com> wrote: >>>> >>>> >>>> Hi Michaela, >>>> >>>> Like you, I'm just a web-developer. >>>> >>>> I don't believe the suggestion from John breaks the classic >>>> username/password model. >>>> >>>> It just allows the website to say "this user has logged in"... and >>>> having done that, the browser will keep client side data around a >>>> bit longer (e.g. cookies, localStorage, IndexedDB, etc). >>>> >>>> This could also be used to remind people of all the websites they >>>> are currently logged into. >>>> >>>> Now there is a problem - bad websites, who just want their tracking >>>> cookies to last a bit longer, they could simply say the user has >>>> just logged in, even if they haven't. >>>> >>>> This is why John made some suggestions on how to avoid that abuse - >>>> the use of WebAuthn or a Password Manager is a good signal, but the >>>> suggestion of forcing the user though a "login flow" that the "the >>>> browser can check" is another approach that might work. >>>> >>>> I'm not sure what that login flow will look like... but how about, >>>> a form that needs to contain an input type="password", and another >>>> field that looks like a username field >>>> (autocomplete="username/email"), where the username is temporarily >>>> stored by the browser... if those fields are filled in by the user, >>>> and submitted to the server by a user action (e.g. they clicked a >>>> submit button), and within 3 minutes the `navigator.setLoggedIn()` >>>> method is called with the same username (assuming either a POST to >>>> a new page, or fetch/XMLHttpRequest), then I'd suggest that was a >>>> good indication of a login. >>>> >>>> Craig >>>> >>>> >>>> >>>> >>>> On Thu, 12 Sep 2019 at 03:04, Michaela Merz >>>> <michaela.merz@rollofone.com <mailto:michaela.merz@rollofone.com>> >>>> wrote: >>>> >>>> >>>> Dear WebAppSec: >>>> >>>> As a (very-) long time web-developer, I'd like to add my two >>>> cents. While there is ample reason for creating a better way of >>>> securing logins, I don't feel comfortable with leaving all >>>> classical username/password methods behind. This explainer >>>> proposes the usage of "trustworthy" login methods and suggests >>>> WebAuthn, password manager or federated login mechanism or "a >>>> flow according to rules that the browser can check". Now - what >>>> is wrong with this? Nothing - in principal. The login-process >>>> is, however, a very private matter between a user and a >>>> web-site. Some users may very well choose not to store their >>>> credentials in password managers, use federated logins or allow >>>> their FIDO key be used for certain websites. Until now, the >>>> browsers can be left out of the login-process and that is what >>>> some users want or even need. Therefore - any way of making >>>> logins more secure must continue to provide mechanisms that >>>> keep the confidentiality (nothing is ever transfered to or >>>> stored in the browser). We already provide 2FA using USB / NFC >>>> U2F keys on browsers that support it - though most users find >>>> that method not too convincing. I must warn against any attempt >>>> to force browser logic or any federated mechanism into the most >>>> principal communications between a user and the website she trusts. >>>> >>>> Thank you. >>>> >>>> Michaela >>>> >>>> On 9/11/19 5:09 PM, John Wilander wrote: >>>>> >>>>> >>>>> Hi WebAppSec! >>>>> >>>>> TPAC is around the corner and one of the agenda items is >>>>> "Login API” with my name attached to it. Below is an explainer >>>>> of what we want to achieve. I think Wendy is working on >>>>> an “Unofficial Drafts” repo for our working group where I can >>>>> put this for more of issue tracking style feedback. But I >>>>> wanted to get something out today since there’s not much time >>>>> left before we meet in Fukuoka. >>>>> >>>>> Looking forward to the event and your thoughts on IsLoggedIn. >>>>> >>>>> Regards, John >>>>> >>>>> >>>>> # Explainer: IsLoggedIn >>>>> >>>>> >>>>> ## Motivation >>>>> >>>>> We need a way for websites to declare to the browser that the >>>>> user is logged in or out, and for those declarations to be >>>>> trustworthy. This is why: >>>>> >>>>> >>>>> ### The Browser Should Know Where You’re Logged In >>>>> >>>>> In olden times, Basic/Digest Authentication offered a way for >>>>> browsers to know where the user was logged in and help them to >>>>> stay logged in. Those technologies are obsolete for many >>>>> reasons. Today, WebAuthn <https://w3c.github.io/webauthn/> and >>>>> password managers (including the use of Credential Management >>>>> <https://w3c.github.io/webappsec-credential-management/>) >>>>> offer a browser-managed way to log in but those features >>>>> neither cover the expiry of the logged in session nor the act >>>>> of logging out. We have yet to standardize a way for browsers >>>>> to manage the logged in status. >>>>> >>>>> >>>>> ### The Current (Bad) Behavior Is “Logged In By Default” >>>>> >>>>> For the purposes of client-side storage/state, the behavior of >>>>> the web platform has been “logged in by default,” meaning as >>>>> soon as the browser loads a webpage, that page can store data >>>>> virtually forever on the device, and the browser may have to >>>>> treat the user as logged in to that website. That is a serious >>>>> privacy issue. Long term storage should instead be tied to >>>>> where the user is truly logged in. >>>>> >>>>> DOM storage such as IndexedDB doesn’t even have an expiry >>>>> functionality, making it impossible for websites who use these >>>>> storage mechanisms to state any guarantees on when traces of a >>>>> visit to their site will go away. >>>>> >>>>> As an additional note, allowing an ever growing, never >>>>> expiring pile of website data from sites the user may have >>>>> visited just once is bad for disk space and backup space. >>>>> >>>>> >>>>> ### Clearing Website Data May Log Users Out >>>>> >>>>> Browsers may try to fix or mitigate the privacy implications >>>>> of “logged in by default” by cleaning up storage and state at >>>>> some cadence. Browsers may also evict cookies because of >>>>> storage limits or truncate cookie request headers because of >>>>> header limits. If the browser doesn’t know where the user is >>>>> logged in, website data cleaning or limits may inadvertently >>>>> log the user out of some websites, leading to a bad user >>>>> experience. >>>>> >>>>> >>>>> ## Straw Man Proposal >>>>> >>>>> Below we present a straw man proposal for how a web API for >>>>> logged in status could look and work. This is a starting point >>>>> for a conversation, not a fully baked proposal. >>>>> >>>>> >>>>> ### API >>>>> >>>>> Here’s how the API for setting IsLoggedIn to true could look: >>>>> navigator.setLoggedIn( >>>>> username: non-whitespace string of limited length, >>>>> credentialTokenType: “httpStateToken” OR “legacyAuthCookie”, >>>>> optionalParams { } >>>>> ) –> Promise<void> >>>>> The returned promise would resolve if the status was set and >>>>> reject if not. The API could potentially take an expiry >>>>> parameter but here we’re assuming that a designated HTTP State >>>>> Token >>>>> <https://mikewest.github.io/http-state-tokens/draft-west-http-state-tokens.html> or >>>>> “legacy auth cookie” manages the expiry of the login through >>>>> their own mechanisms. >>>>> >>>>> Here’s how the API for setting IsLoggedIn to false could look: >>>>> >>>>> |navigator.setLoggedOut(optionalUsername) –> Promise<void>| >>>>> >>>>> The optional username parameter highlights that we might want >>>>> to support concurrent logins on the same website which would >>>>> require the site to keep track of who to log out and >>>>> credential tokens to be scoped to user names. >>>>> >>>>> Here’s how the API for checking the IsLoggedIn status could look: >>>>> >>>>> |navigator.isLoggedIn() –> Promise<bool>| >>>>> >>>>> This last API could potentially be allowed to be called by >>>>> third-party iframes that do not currently have access to their >>>>> cookies and website data. The iframes may want to render >>>>> differently depending on whether the user is one of their >>>>> logged in customers or not. >>>>> >>>>> >>>>> ### Defending Against Abuse >>>>> >>>>> If websites were allowed to set the IsLoggedIn status whenever >>>>> they want, it would not constitute a trustworthy signal and >>>>> would most likely be abused for user tracking. We must >>>>> therefore make sure that IsLoggedIn can only be set when the >>>>> browser is convinced that the user meant to log in or the user >>>>> is already logged in and wants to stay logged in. >>>>> >>>>> Another potential for abuse is if websites don’t call the >>>>> logout API when they should. This could allow them to maintain >>>>> the privileges tied to logged in status even after the user >>>>> logged out. >>>>> >>>>> There are several ways the browser could make sure the >>>>> IsLoggedIn status is trustworthy: >>>>> >>>>> * Require websites to use of WebAuthn or a password manager >>>>> (including Credential Management) before calling the API. >>>>> * Require websites to take the user through a login flow >>>>> according to rules that the browser can check. This would >>>>> be the escape hatch for websites who can’t or don’t want >>>>> to use WebAuthn or a password manager but still want to >>>>> set the IsLoggedIn bit. >>>>> * Show browser UI acquiring user intent when IsLoggedIn is >>>>> set. Example: A prompt. >>>>> * Continuously show browser UI indicating an active logged >>>>> in session on the particular website. Example: Some kind >>>>> of indicator in the URL bar. >>>>> * Delayed browser UI acquiring user intent to stay logged >>>>> in, shown some time after the IsLoggedIn status was set. >>>>> Example: Seven days after IsLoggedIn was set – “Do you >>>>> want to stay logged in to news.example?” >>>>> * Requiring engagement to maintain logged in status. >>>>> Example: Require user interaction as first party website >>>>> at least every N days to stay logged in. The browser can >>>>> hide instead of delete the credential token past this kind >>>>> of expiry to allow for quick resurrection of the logged in >>>>> session. >>>>> >>>>> >>>>> ### Credential Tokens >>>>> >>>>> Ideally, a new IsLoggedIn API like this would only work with >>>>> modern login credentials. HTTP State Tokens could be such a >>>>> modern piece. However, to ensure a smooth path for adoption, >>>>> we probably want to support cookies as a legacy option. >>>>> >>>>> Both HTTP State Tokens and cookies would have to be explicitly >>>>> set up for authentication purposes to work with IsLoggedIn. In >>>>> the case of both of these token types, we could introduce >>>>> a |__auth-| prefix as a signal that both the server and client >>>>> consider the user to be logged in. Or we could allow HTTP >>>>> State Token request and response headers to convey login >>>>> status. Note that sending metadata in /requests/ differs from >>>>> how cookies work. >>>>> >>>>> The expiry of the token should be picked up as a logout by >>>>> IsLoggedIn. >>>>> >>>>> Cookies have the capability to span a full registrable domain >>>>> and thus log the user in to all subdomains at once. HTTP State >>>>> Tokens have a proper connection to origins but can be declared >>>>> to span the full registrable domain too. We should probably >>>>> let the credential token control the scope of the IsLoggedIn >>>>> status. >>>>> >>>>> Explicitly logging out should clear all website data for the >>>>> website, not just the credential token. The reverse, the user >>>>> clearing the credential token (individually or as part of a >>>>> larger clearing of website data), should also log them out for >>>>> the purposes of IsLoggedIn. >>>>> >>>>> >>>>> ### Federated Logins >>>>> >>>>> Some websites allow the user to use an existing account with a >>>>> federated login provider to bootstrap a new local user account >>>>> and subsequently log in. The IsLoggedIn API needs to support >>>>> such logins. >>>>> >>>>> First, the federated login provider needs to call the API on >>>>> its side, possibly after the user has clicked a “Log in with >>>>> X” button: >>>>> >>>>> |navigator.initiateLoggedInFederated(destination: secure >>>>> origin) –> Promise<void>| >>>>> >>>>> For the promise to resolve, the user needs to already have the >>>>> IsLoggedIn status set for the federated login provider, i.e. >>>>> the user needs to be logged in to the provider first. >>>>> >>>>> Then the destination website has to call the API on its side: >>>>> navigator.setLoggedInFederated( >>>>> loginProvider: secure origin, >>>>> username, >>>>> credentialTokenType, >>>>> optionalParams { } >>>>> ) –> Promise<void> >>>>> The promise would only resolve if the loginProvider had >>>>> recently called |setLoggedInFederated()| for this destination >>>>> website. >>>>> >>>>> >>>>> ## Challenges and Open Questions >>>>> >>>>> * *Grandfathering*. Some websites may not want to prompt an >>>>> already logged in user or take them through an additional >>>>> login flow just to set the IsLoggedIn status. >>>>> * *Expiry limit*. What is a reasonable limit for expiry >>>>> without revisit/re-engagement? >>>>> * *Single sign-on*. If the browser supports First Party Sets >>>>> <https://github.com/krgovind/first-party-sets>, it may >>>>> support single sign-on within the first party set, for >>>>> instance with an optional parameter |includeFirstPartySet: >>>>> [secure origin 1, secure origin 2]|. The browser would >>>>> check the integrity of the first party set claim and >>>>> potentially ask the user for their intent to log in to >>>>> multiple websites at once before setting the IsLoggedIn >>>>> status for all of them. The expiry of the login status for >>>>> the first party set would likely be controlled by the >>>>> expiry of the credential token for the single sign-on >>>>> origin. However, there is not browser agreement on how to >>>>> support First Party Sets in a privacy preserving way >>>>> (see Issue 6 >>>>> <https://github.com/krgovind/first-party-sets/issues/6> and Issue >>>>> 7 <https://github.com/krgovind/first-party-sets/issues/7>). >>>>> * *A full-fledged **Login API*. As we’ve discussed >>>>> IsLoggedIn, we’ve also talked about what an API >>>>> that actually logs the user in would look like, i.e. >>>>> navigator.logIn(), navigator.logOut(), and >>>>> navigator.isLoggedIn(), where either credential tokens are >>>>> passed to the browser or the browser is asked to generate >>>>> them. That may be where the WG prefers to go so we’re >>>>> adding it here. >>>>> >>>>> >>>> -- >>>> Email is unsafe. Send confidential text or data via >>>> packfrog: https://packfrog.com/bt?ee=9b26b31bd >>>> >> -- >> Email is unsafe. Send confidential text or data via >> packfrog: https://packfrog.com/bt?ee=9b26b31bd > -- Email is unsafe. Send confidential text or data via packfrog: https://packfrog.com/bt?ee=9b26b31bd
Received on Thursday, 12 September 2019 17:21:57 UTC