W3C home > Mailing lists > Public > public-webappsec@w3.org > September 2019

Re: Explainer: IsLoggedIn (in preparation for TPAC)

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


On Thu, 12 Sep 2019 at 03:04, Michaela Merz <michaela.merz@rollofone.com>

> 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

This archive was generated by hypermail 2.4.0 : Friday, 17 January 2020 18:55:08 UTC