Re: Opting in to cookies - proposal

Maciej Stachowiak wrote:
> On Jun 13, 2008, at 10:45 PM, Jonas Sicking wrote:
>> Maciej Stachowiak wrote:
>>> On Jun 13, 2008, at 5:20 PM, Jonas Sicking wrote:
>>>> Maciej Stachowiak wrote:
>>>>> On Jun 13, 2008, at 4:56 PM, Jonas Sicking wrote:
>>>>>> Hi All,
>>>>>> Since I haven't received any feedback on the various straw-men in 
>>>>>> the "Opting in to cookies" thread, I'll send a full proposal 
>>>>>> (wrote most of this yesterday, Thomas wrote some opinions on 
>>>>>> cookies this morning).
>>>>>> First off, as before, when I talk about "cookies" in this mail I 
>>>>>> really
>>>>>> mean cookies + digest auth headers + any other headers that carry the
>>>>>> users credentials to a site. However i'll just use the term "cookies"
>>>>>> for readability, and since that is on the web currently the most
>>>>>> common carrier of credentials.
>>>>>> So here goes:
>>>>>> When loading a resource using access-control associate the request 
>>>>>> with
>>>>>> a "with credentials" flag.
>>>>>> When the resource is loaded using an URI which starts with the string
>>>>>> "user-private:" set the "with credentials" flag to true. Otherwise 
>>>>>> set
>>>>>> it to false.
>>>>> How could an http or https URI start with the string 
>>>>> "user-private:"? Are you proposing a new URI scheme?
>>>> My proposal is for nesting schemes, so you'd load 
>>>> user-private:
>>> That strikes me as distasteful. I would prefer to see a separate 
>>> includeCrossSiteCredentials parameter on XHR somewhere than to use 
>>> in-band signalling via the URL, if we feel this is needed.
>> The advantage with putting it as part of the URI is that it is agnostic
>> to which method used for loading. So for example inside XSLT you could 
>> do:
>> <xsl:for-each
>>  select="document('user-private:')/adr/*">
>>  Name <xsl:value-of select="@name">
>> </xsl:for-each>
>> to incorporate private data. This is one of the design goals of
>> Access-Control, that it is a generic loading mechanism, rather than
>> limited to a particular API.
> The downsides of inventing a URI scheme include:
> 1) URIs using this scheme will not parse into components properly (the 
> feed: scheme has this problem)
> 2) The scheme really should be registered through IANA, which will be a 
> bureaucratic hassle
> 3) IANA would probably be hesitant, because user-private: does not 
> describe a new resource access method, it just describes what headers 
> you want to send, which in http is separate from the URI
> 4) It is in fact a valid point that this violates the design of URI schemes

All good points. I guess I'm more ok with it since we already deal with 
this stuff in gecko a good bit, as we already do support nested schemas.

> 5) Code throughout the system will have to know to special-case this URI 
> scheme to treat it as equivalent to the corresponding HTTP URI

Not neccesarily, you'd just need to strip the "user-private:" part in 
the Access-Control implementation which means that most of the system 
would just see the HTTP URI.

> Compared to that, I think the benefit of retrieving user-specific XSL 
> stylesheets with credentials seems pretty low.
> In general, even though Access-Control originated as a generic 
> mechanism, the XHR use case is clearly far more important to the Web 
> than any other and we shouldn't stuff out-of-band parameters in the URI 
> just for the sake of the other relatively minor use cases.

I do think there is a lot of value in a generic algorithm. Though I 
would be fine with doing the flag too. We can always consider a URI 
schema in a second version if there is a demand for it.

>>> However, I am not sure I understand the purpose of extra client-side 
>>> opt-in to cookies. Presumably the client side is cross-site and 
>>> therefore not under control of the server. So if the server is 
>>> careless about cross-site requests that include cookies or other 
>>> credentials, then I do not see how an opt-in mechanism on the client 
>>> side helps at all.
>> The opt-in ultimately comes from the server through the
>> Access-Control-With-Credentials header. However for GET requests we 
>> don't know if the server is going to opt in or not at the time when 
>> the request is made. Therefore the client must opt in first, however 
>> if the client opts in but the server doesn't, the response from the 
>> server is discarded.
> So it's just to save a round trip for the cookies case for GET requests? 
> (A round trip the first time only since the method check result may be 
> cached?)

If we didn't opt in on the client side we would effectively in very many 
cases have to require an extra OPTIONS request, even for public data. 
The reason is that often the user will have cookies set even on sites 
that just deal with public data. For example on craigslist I have two 
cookies set even though any mashup involving craigslist would just deal 
with public data.

> If you assume opting into cookies is common on the server side, then the 
> XHR implementation could send GETs with cookies but deny data and retry 
> the request unless the server gives an "I opted into cookies" header in 
> the response.

I considered that. However the result would likely be that sites would 
opt in to cookies just to lower the load on their servers, which would 
negate the usefulness of the cookie opt-in.

> If you assume the opposite is more likely then you can 
> send the GET without credentials first and retry if the server responds 
> that it would have wanted cookies (and you can cache this).

This is unlikely to be well received by the people that argued for the 
Access-Control-Policy-Path feature since it would double the number of 
requests if you were interacting with a number of distinct URIs. We 
could come up with some way of using Access-Control-Policy-Path directly 
in GET requests, but that feature is complicated enough as it is, and I 
would much prefer to keep GET requests simple as that is likely going to 
be the vastly common case.

> For the common case of XHR, we could also add a separate boolean 
> attribute specifying whether the client thinks the server wants cookies, 
> to suggest which of the above two guesses to take.
 > That would work for all cases, with extra requests pretty rare, and
 > would not require inventing a URI scheme.

If we do that then I think we should just use that XHR boolean be the 
"with credentials" flag in my originally proposed algorithm. I.e. just 
do one request based on what the boolean says and fail if the server 
didn't agree.

> I must say though, this is starting to sound complex and I am not 
> totally convinced of the need to make servers opt in to getting cookies. 
> Is it really a likely mistake that someone would take affirmative steps 
> to enable cross-site access to a per-user resource, but then neglect to 
> check whether requests are cross-site and act appropriately?

I do think there is a big risk of that yes. I do think that many sites 
that today serve public data do have a few pages in there which contain 
forms or other pages that serve user specific data.

Even something as simple as a news site that largely serves public news 
articles might have a cookie where the user has chosen a home location 
for local news. This is the case on the news site I use for example, it 
usually just serves a standard list of news, but if I give it my home 
zip code, it will additionally serve a section of local news.

This is something that could very easily be overlooked by an 
administrator that just configures his server to add a "Access-Control: 
allow<*>" header using a site-wide configuration file, without going 
through all CGI scripts on the server and teaching the ones that honor 
cookies to ignore the cookies for cross-site requests.

> And if the 
> administrator of such a server thoughtlessly enabled cross-site access 
> without thinking about the consequences, would they not be equally 
> likely to enable cross-site cookies without thinking about the 
> consequences?

Not more likely than someone adding any other header without knowing 
what it does. This is why I designed my proposal such that opting in to 
cookies is a separate "step".

As described in my initial post here
very little security considerations needs to be done by a server 
operator that wants to publish public data if he can opt in without cookies.

When publishing private data there is always a lot more considerations 
that needs to be done. You have to make sure to ask the user first 
before sharing his/her data, you have to make sure to only serve the 
data that the user has opted in to (which likely means that you'd want 
to set up separate URIs). We can only hope that people that decide to 
share private data think before doing so.

> It seems like we are adding a lot of complexity (and therefore more 
> opportunity for implementation mistakes) for a marginal reduction in the 
> likelihood of server configuration errors.

I think the ability to separate sharing of private data from sharing of 
public data is a huge help for server operators. So I think this is much 
more than a marginal reduction of configuration errors.

I asked this in a separate thread already, but have you guys at apple 
had your security people look through the spec. Were they comfortable 
both with always sending cookies as well as always enabling all HTTP 
methods and headers?

/ Jonas

Received on Saturday, 14 June 2008 11:24:35 UTC