W3C home > Mailing lists > Public > public-webappsec@w3.org > May 2017

Re: Cookies under Suborigins

From: Devdatta Akhawe <dev.akhawe@gmail.com>
Date: Wed, 10 May 2017 08:38:47 -0700
Message-ID: <CAPfop_0AJCXqX475pfwostOpSO_WRJFj_io=p-Ox2Di51gc8bA@mail.gmail.com>
To: Jochen Eisinger <eisinger@google.com>
Cc: Aleksandr Dobkin <dobkin@google.com>, "public-webappsec@w3.org" <public-webappsec@w3.org>, Mike West <mkwst@google.com>
Hey Alex

I agree with Jochen. We should punt on this for v1 in the interest of
getting something useful, not perfect, out.

I am curious: why doesn't a polyfill that postMessages to an iframe that is
on the physical origin work for you? This also allows you to implement
policies of arbitrary complexity. In the spirit of extensible web, I think
this is far more practical than the spec trying to mandate what's right and
what's wrong: we will screw this up. The web is very complex and diverse.

cheers
Dev

On 9 May 2017 at 02:34, Jochen Eisinger <eisinger@google.com> wrote:

>
>
> On Tue, May 9, 2017 at 5:39 AM Aleksandr Dobkin <dobkin@google.com> wrote:
>
>> Documents are cookie-averse by default in suborigined content
>> (document.cookie returns the empty string and setting document.cookie does
>> nothing). Much of our content makes use of Google Analytics and the current
>> behavior of the analytics script is to silently stop working when cookies
>> are not working. For us at Google, to achieve broad adoption of Suborigins
>> in legacy content, it's sufficient to set the 'unsafe-cookies' flag. This
>> is because, with a few possible exceptions, we do not directly store CSRF
>> tokens in cookies and the values of JS-accessible cookies are not very
>> sensitive.
>>
>> However, for many sites that store CSRF tokens in cookies, the
>> 'unsafe-cookie' will indeed be unsafe. I would for us to consider
>> alternative designs that would make it easier to adopt Suborigins out of
>> the box, while still being safe for everyone.
>>
>> Google Analytics (and I suspect similar products) use cookies to store
>> IDs for user and session tracking. Analytics, for example, uses the '_ga'
>> cookie. Nevertheless, to keep existing script working without modification,
>> it is necessary to permit suborigined content to read and write certain
>> cookies.
>>
>> I suspect the reason for using cookies is mainly historical, and
>> sessionStorage could be used in most cases. However, cookies are
>> occasionally used is for tracking across subdomains of a TLD and across
>> HTTP and HTTPS versions of a site, and here, sessionStorage is not a good
>> replacement.
>>
>> I briefly looked at the CSRF protection implementation used by Dropbox.
>> Dropbox stores the CSRF token in a cookie called '__Host-js_csrf' (which is
>> httponly) as well as a cookie called 't' (which is normally available via
>> document.cookie). If the suborigned content gets access to the 't' cookie,
>> it would be able to attack other, non-suborigined, content on the domain.
>>
>> Dropbox will need to change its CSRF mechanism when adapting applications
>> for suborigins, though, and I don't think there is a good way to avoid
>> doing so. It's not safe to reuse the same token among multiple suborigins,
>> so per-suborigin tokens would have to be used. This simplest way to do this
>> would probably be to compute tokens as hmac(value=suborigin,
>> key=site_wide_csrf) and embedding them in HTML.
>>
>> Considering the three requirements above (compat with legacy tracking
>> scripts, cross-domain tracking, and compat with CSRF cookies), we can come
>> up with different designs and see how well they meet the requirements. I've
>> summarized my findings in the following table. The coumn headings list
>> requirements and various design ideas are listed in the row headings.
>>
>>
>>
>>                          | compat w/ legacy | cross-domain | safe w/
>> legacy
>>                          | tracking scripts | tracking     | CSRF cookies
>> =========================+==================+==============+
>> ================
>> No cookies               | No               | No           | Yes
>> (current implementation) |                  |              |
>> -------------------------+------------------+--------------+
>> ----------------
>> No cookies restrictions  | Yes              | Yes          | No
>> -------------------------+------------------+--------------+
>> ---------------
>> Prefixed access only     | No               | No           | No
>> -------------------------+------------------+--------------+
>> ----------------
>> Transparent prefixes     | Partial*         | No           | Yes
>> -------------------------+------------------+--------------+
>> ----------------
>> Local cookies            | Partial**        | No           | Yes
>> -------------------------+------------------+--------------+
>> ----------------
>> Everything but __Host-   | Yes              | Yes          | mostly No
>> -------------------------+------------------+--------------+
>> ----------------
>> Cookie whitelist         | Yes***           | Yes***       | Yes
>> -------------------------+------------------+--------------+
>> ----------------
>> Cookie blacklist         | Yes              | Yes          | Yes****
>>
>> * Yes, but results in cookie inflation and breaks cross-domain tracking.
>> ** Yes, but breaks cross-domain tracking.
>> *** Yes, but requires configuration.
>> **** Yes,  but requires and configuration and is dangerous.
>>
>> Explanation of designs:
>>
>> No cookies: Document is cookie-averse. Assigning to document.cookie is a
>> no-op. cookie.document is always blank.
>>
>> No cookie restrictions: Document gets access to document.cookie as though
>> it was not suborigined.
>>
>> Prefixed access only: Document can only get and set cookies whose names
>> begin with a per-suborigin prefix. Setting document.cookie only works if
>> the cookie names begins with __Sub_{name}-. document.cookie only exposes
>> cookies that begin with the same prefix.
>>
>> Transparent prefixes: Same as above except that prefix are automatically
>> added when assigning to document.cookie. Reading from document.cookie
>> returns unprefxed cookies.
>>
>> Local cookies: document.cookie string is stored in a hidden LocalStorage
>> field. So assigning to document.cookie works but these cookies are not
>> included in the Cookie header
>>
>> Everything but __Host-: Access to cookies is allowed except for __Host-
>> prefixed cookies.
>>
>> Cookie whitelist: Cookie access is allowed to cookies whose names are
>> whitelisted in the Suborigins header. Setting document.cookie is only
>> allowed if the cookie name is on the whitelist. document.cookie only
>> exposes cookies whose names are on the whitelist.
>>
>> Cookie blacklist: Same as above, but with a blacklist.
>>
>> What does everyone think of these solutions? Are we open to potentially
>> adopting any of them?
>>
>> From the list above, 'local cookies' and 'cookie whitelist' designs meet
>> most of the requirements. Personally, I think the 'local cookies' solution
>> would be a useful to have and could be safely enabled by default. The
>> 'cookie whitelist' feature might be useful as well, but is more dangerous
>> and also requires a whitelist be specified.
>>
>
> It looks like the "local cookies' could also be implemented as a small
> polyfill, right?
>
> "Regular cookies" and "no cookies" are easy to spec, while the new models
> you describe would require defining a new thing, so I'd lean towards
> punting this to after the v1 has launched, wdyt?
>
>
>
>>
>> -Alex
>>
>
Received on Wednesday, 10 May 2017 15:39:41 UTC

This archive was generated by hypermail 2.3.1 : Monday, 23 October 2017 14:54:23 UTC