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

Re: Cookies under Suborigins

From: Aleksandr Dobkin <dobkin@google.com>
Date: Wed, 10 May 2017 18:28:36 -0700
Message-ID: <CAJGyu7VtUYP0JMryz=24gLCU6bvoSf5mtmjg6QeZmj3wWBXChA@mail.gmail.com>
To: Devdatta Akhawe <dev.akhawe@gmail.com>
Cc: Jochen Eisinger <eisinger@google.com>, "public-webappsec@w3.org" <public-webappsec@w3.org>, Mike West <mkwst@google.com>
We want to roll out suborigins on our static content pages en mass, e.g.
all the pages on www.google.com/about and polyfills would be a lot of work.
The right way to do it would be to update the templates that are used to
generate the HTML pages. There several challenges:

 1) Sometimes it is hard to find the template. If you know you have page X,
finding template Y for it is nontrivial. We have thousands of individual
 2) Sometimes it is hard to export the template to HTML correctly because
the config files are in a bad state, not present, bitrotted, etc. The
templates the template depends on are updated from time to time, and
exporting can result in unexpected changes in output, so updates frequently
require manual QA.

We could insert the polyfills in the HTML files directly, but then the
polyfill would be be lost the next time the templates are exported, and the
error (broken analytics) might not be noticed right away. We could build
some automation to fix this, though.

It's a lot easier to deploy if it's just a flag in a header.

I'm okay to punt on this until after v1. For us, the 'unsafe-cookie' flag
seems sufficient and safe. I think it would be worth it if we can spec
something so that suborigins works better out of the box with commonly-used

On Wed, May 10, 2017 at 8:38 AM, Devdatta Akhawe <dev.akhawe@gmail.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 Thursday, 11 May 2017 01:29:11 UTC

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