Re: Re: [XHR] anonymous flag

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..


Hallvord R. M. Steen
Core tester, Opera Software

Received on Tuesday, 21 May 2013 17:41:12 UTC