- 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