Re: Explainer: IsLoggedIn (in preparation for TPAC)

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