Re: Comment on minutes ## With Credentials flag etc
Tim Berners-Lee <[email protected]> Fri, 1 Apr 2016 14:26:46 -0400
| Newsgroups | gmane.org.w3c.tag |
|---|---|
| Message-ID | <[email protected]> |
Thank you Jonas, for that clarification. some response inline. > On 2016-01 -21, at 01:24, Jonas Sicking <[email protected]> wrote: >=20 > On Mon, Jan 18, 2016 at 3:27 PM, Mark Nottingham <[email protected]> = wrote: >> ... or at least the motivations behind the decisions explained. It's = pretty impenetrable now, and even security folks don't profess to know = all of the details behind CORS any more. >=20 > I'm bummed to hear that aspects of CORS is still confusing even to the > TAG. This stuff likely needs to get documented someplace. I had hoped > that it'd get documented in the spec, but maybe there's a better > place? Perhaps the problems are that it is complicated, rather arbitrary, and = not derived from general principles.. >=20 > I'm not actually sure what exact confusion is being discussed in this > thread is, so I'll address some of the questions I most commonly get. >=20 > Q: What does the withCredentials flag do. > A: When it's set to false, requests are sent containing only the > information provided by the requesting website. I.e. the requesting > website's provided URL, headers and request body. The only information > that's added by the browser is information that's hardcoded into the > browser and does not depend on user information. So for example the > user-agent header. No cookies, authentication headers, or client-side > certificates are added by the browser to the request before it is sent > to the target website. >=20 > However setting withCredentials to false does not prevent the > requesting website from adding credentials through cookie headers, > authentication headers, URL parameters or any other way that's exposed > through the API which triggered the request. >=20 > Additionally, the response data that would normally affect the client > data storage is ignored. So for example set-cookie response headers > are not written to the browsers cookie storage. The returned response > is also not stored in the normal http cache, though if appropriate > browsers may store it in a specific > "CORS-requests-with-withCredentials-set-to-false" cache. >=20 > When withCredentials is set to true, requests are handled like > "normal" requests do in a browser. That means that cookies from the > users cookie storage are added based on the target URL. Cached > authentication data is added through the authentication header. >=20 > The response is likewise processed like normal, so set-cookie headers > are processed and the response is cached, if appropriate, in the > normal browser http cache. >=20 > Q: Why are security checks performed when withCredentials is set to = false? > A: Because the user, and the user's browser, might be behind a > firewall and so might be able to access servers which a website would > otherwise not be able to access. >=20 > Sadly there is no, to me, known mechanism for detecting if a given > server is behind a firewall. That=E2=80=99s a long rathole but ... 1) If your local IP address is the same as the one you get from a public = IP reflector then you are not behind a firewall 2) If your IP address starts with 192.168=E2=80=A6 then you are behind a = firewall =E2=80=A6 =20 3) BUT that isn=E2=80=99t the point, you can be outside a firewall and = still have privileged access by your IP address. 4) And you could also be behind a carrier-grade NAT box but not have any = privilege access as a result.=20 One possible but hard route is to pursue something like the router = telling your machine whether it has no privileged access, which would = then enable a lot of stuff. So public internet spaces would set the = flag, which would then mean the browsers would do less preflights, = wasted attempts to access stuff, etc and so the browser would run more = quickly for less bandwidth. > Q: Is it safe to always set "Access-control-allow-origin: *" on all > responses from a server. > A: As long as the server is connected to the public internet, yes it > is. It does not leak any information that couldn't be loaded using > curl or any other non-browser HTTP client. >=20 > If the server is behind a firewall and might contain sensitive > information, the header should not be added. Well, the header should be added for any public resource. Some servers in fact handle the access control for the different = resources on the site, and so in that case they ought to use that = function to drive the headers automatically. THAT is what should be = coded up in the common servers. That would help the server manager do the right thing. >=20 > Q: Why does CORS not allow "Access-control-allow-origin: *" together > with withCredentials=3Dtrue? > A: It was felt that this was too big of a foot gun. >=20 > CORS was designed not long after Adobe had added the crossdomain.xml > feature to Flash Player. The crossdomain.xml feature allows webserver > administrators to easily indicate that the server contains resources > that should be loadable from other origins. The feature only allowed > "normal" requests, i.e. requests similar to ones that CORS makes when > withCredentials=3Dtrue. >=20 > When crossdomain.xml was released many websites opted in allowing data > to be read from other websites in order to share some public data that > was hosted on the server. Unfortunately they forgot that some other > URLs on the server served sensitive user data. The result was that > relatively quickly after the release of the crossdomain.xml multiple > websites leaked sensitive user data. >=20 > You could argue that the problem was that crossdomain.xml was > different since it is a per-server configuration file, whereas CORS > uses per-URL headers. Hence CORS would be less prone to server > administrators accidentally opting in to sharing on URLs that server > user sensitive data. >=20 > However in practice many (most?) popular web servers allow adding > configuration files which add static http headers to all URLs under a > given directory. So in practice on many servers it would have been > just as easy to make the same mistake with CORS. Any arguments about making things easy or difficult for server admins to=20= shoot themselves in the foot coming from a non-optimal attitude. To first order, the system must implement a security protocol which = allows people to do the right thing =E2=80=94 to give the right access to the = right resources by the right people and origins. Yes, by all means make the server Q: Why was reflecting the incoming origin in the header the thing which = was picked as the ay of saying =E2=80=9Cyes this really is public=E2=80=9D? Why = not =E2=80=9Caccess-control-allow-origin **=E2=80=9D or something It is a pain to code, needs two or three lines of not-newbie-obvious = .htaccess in Apache, etc.=20 Result? the recipe is sent around and new server code does it by default for everything. Because CORS is such a pain for developers to deal with on the client = side, with no error codes, etc that servers who want stuff to just work, and slap in the strongest CORS = medicine they find on the net. > Q: Why does CORS not allow listing multiple origins, or allow pattern > matching, in the "Access-control-allow-origin" header? > A: It was felt that if the server uses dynamic server-side logic to > generate responses for a given URL, that they could also then > dynamically generate the appropriate Access-control-allow-origin > header. > For servers that generate static responses you can generally simply > use "Access-control-allow-origin: *=E2=80=9D. Well no, not if they only want 7 specific domains to have access. > Keep in mind that static > responses can generally be read from non-browser HTTP clients like > curl anyway. >=20 > This doesn't account for static responses which are password protected > using either cookies or auth headers. So yeah, our solution here is > not perfect, but we decided to opt for simplicity. >=20 > My personal hope was also that generic server modules would be written > to handle CORS support and which would simplify situations like this. > I'm not sure if such modules exist yet or not. There are lots. They may be turned on by default. A concern is they = tend to just defeat CORS=20 and they don=E2=80=99t necessarily distinguish between public resources = and others. Also people use CORS proxies to access the web, which are associated > [...] >=20 >=20 > If I'm not addressing the concern/questions from the TAG then please > let me know. I think the top two issues the TAG had is a) Having the withCredentials flag as a parameter to fetch() is broken. = In general the middleware which calls fetch() will not have magic = application-level knowledge of which resources it is going to fetch are = public, which are private. So a general the fetch has to work without = that hint, and do the right thing. b) For a webapp which needs to load stuff from the net, the lack of = clear error conditions makes it hard to understand what is going on. = A good=20 c) Asking server writers to do the origin reflection thing is = unreasonable >=20 > I'd really love it if this type of information could make it into the > spec in a way that is understandable to more people. >=20 > / Jonas >=20