- From: Craig Francis <craig.francis@gmail.com>
- Date: Thu, 12 Sep 2019 12:55:55 +0100
- To: Michaela Merz <michaela.merz@rollofone.com>
- Cc: WebAppSec WG <public-webappsec@w3.org>
- Message-ID: <CALytEkMYGW5D1mLy=P-e=yz3=TZFadnOm8SVX3SNbr8Ak+Nv7Q@mail.gmail.com>
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> 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 > >
Received on Thursday, 12 September 2019 11:56:31 UTC