Anne wrote:

> I don't really feel it's responsible to remove this feature at this
> point without anyone involved in the original discussion speaking up.

Hi all,
you were involved in a discussion [1] regarding UMP and CORS back in 2010. I 
know, it's a while ago, and apparently you had already been discussing this for 
*quite* a while. However, as the saying goes: no good deed goes unpunished, and 
I'd like wider feedback on an issue I've been discussing with Anne - so here's 
another chance to exercise those arguments. My apologies :-o..

I've been working on the XHR test suite, and thus been looking at the spec from 
a JS developer's perspective. From this perspective, I found that the 
withCredentials / anonymous flag features were somewhat confusing, to be more 
specific it was hard to figure out what the point of the anonymous flag really 
was. Some very close reading of the spec helped me figure out that the 
anonymous flag would:

* Disable Origin: and Referer: headers

* Send same-origin requests as if they were cross-origin: require preflights 
where CORS requests require preflights, and the same-origin server must opt-in 
with Access-Control-Allow-Origin and such.

Now, I read through the old thread [1] - all of it, the UMP spec and some other 
related stuff, but still couldn't quite figure out what use cases this was 
meant to solve - so I questioned why we should have the anonymous flag at all 
in [2], [3] and [4]. (Sorry for referencing only my arguments, the interleaved 
E-mails are easy to find from there).

So far in the discussion, I still think we should drop the "anonymous flag" 
feature from the spec. Some more thoughts beyond the arguments in the 
referenced E-mails:

* On the web, the most widely used authorization models are cookies and SSL 
sessions. Authority is rarely if ever defined by Origin and/or Referer - and 
rightly so, since they can easily be faked in server-to-server requests. Some 
sites have traditionally whitelisted certain sites based on Referer to avoid 
"hotlinking" of images, but hacking around such measures is hardly a use case 
we should try to cater for.

Hence, I don't even see much of a theoretical benefit to suppressing Origin.

* On the web, we usually value security-in-depth, i.e. several layers of 
security checks. The UMP model seemed to argue strongly in favour of a single 
point of failure - a token in the URL or in the body of a POST request. It 
seems to me that most services that need securing would want to also check 
Origin, check cookies and/or SSL data. On the surface this is an argument *for* 
the anonymous flag: given the assumption that valuable services do layered 
security, having credentials dropped in requests that may be risky is a Good 
Thing (TM). However, the problem is we put the burden on developers to *set* 
the anonymous flag, to foresee what requests might be risky and take 
precautions, to opt-in to a mode where even same-origin requests become much 
more cumbersome to complete and where their *own* layered security measures 
will fail. This feature is IMHO very hard to use correctly, and can
easily cause unexpected and hard to understand failure modes if used 
incorrectly.

* If we can't easily explain to authors what a feature is for, it won't get 
used.

* Having both withCredentials and anonymous flag is confusing and can give a 
false sense of security as explained in [6].

My preferred solution (which may be a little too "magic") is to turn 
withCredentials into a sort of tri-state flag, where setting 
withCredentials=false disables using cookies/HTTP Auth/existing SSL sessions on 
both same-origin and cross-origin requests, setting withCredentials=true 
enables it for both, and not setting it will leave the default behaviour to use 
authentication on same-origin and omit it for cross-origin requests. (Then drop 
the "anonymous" flag and ignore any requests for being able to suppress 
Referer: and Origin: (unless documented by use cases we want to support).)

Another option might be to drop anonymous flag, "deprecate" withCredentials and 
define a new property called sendCredentials, taking values "sameorigin", 
"always" and "never", with "sameorigin" being the default value. Too bad I'm 
2-3 years late with that suggestion, I think it would have been clearer. 

(Obviously, if we think existing content using withCredentials is written in a 
way that would let us get away with redefining it to being a string, use values 
"sameorigin", "always" and "never" and throw in a small hack translating true 
when set to "always", that would be totally sweet :-D.)


Further, I think that as an extra security precaution, the spec should make it 
absolutely clear that if a CORS-request where withCredentials is *not* set to 
true/always gets redirected to a same-origin URL, credentials must *not* be 
sent while requesting the redirect target. This should close one of the 
existing potential holes and make XHR and CORS a tad more safe by default.

Now, from my practical-JS-author perspective there may be things I'm missing. 
Maybe to do with server implementation details or typical intranet/internet 
boundary behaviours. I fully agree with Anne that it would be good to have 
further input from you all while considering removing the anonymous flag. If 
you can convince me that we need the anonymous flag, we don't have to edit the 
spec to remove it - yay, less work for us editors ;-) - so please discuss..

[1] 
http://lists.w3.org/Archives/Public/public-webapps/2010AprJun/thread.html#msg171
[2] http://lists.w3.org/Archives/Public/public-webapps/2013AprJun/0628.html
[3] http://lists.w3.org/Archives/Public/public-webapps/2013AprJun/0638.html
[4] http://lists.w3.org/Archives/Public/public-webapps/2013AprJun/0714.html
[5] http://lists.w3.org/Archives/Public/public-webapps/2013AprJun/0721.html
[6] http://lists.w3.org/Archives/Public/public-webapps/2013AprJun/0729.html



-- 
Hallvord R. M. Steen
Core tester, Opera Software






Reply via email to