Re: Comment on minutes ## With Credentials flag etc

Jonas Sicking <[email protected]> Tue, 19 Apr 2016 14:58:27 -0700
Newsgroups gmane.org.w3c.tag
Message-ID <CA+c2ei-eG=ObemPJHoZ84fAu66H0ScKa12Gew-MYFD0GN0fQsw@mail.gmail.com>
Indeed. "Access-Control-Allow-Credentials" is also a poor name. It is
quite possible to send credentials without it. It just controls
whether user credentials will be added by the browser or not.

/ Jonas

On Tue, Apr 19, 2016 at 1:43 PM, Brad Hill <[email protected]> wrote:
> It does occur to me how much confusion could have been avoided over the y=
ears by using the keyword 'anonymous-only' instead of * in CORS.  A missed =
opportunity for clarity.
>
>
>
> On 4/19/16, 12:27 PM, "John Kemp" <[email protected]> wrote:
>
>>Hi Brad,
>>
>>Just to mention a piece of (long-ago!) history related to CORS and XHR, a=
s I previously did some TAG analysis on CORS and a related/competing propos=
al, called UMP, in relation to XHR.
>>
>>https://urldefense.proofpoint.com/v2/url?u=3Dhttps-3A__www.w3.org_2001_ta=
g_2010_06_01-2Dcross-2Ddomain.html&d=3DCwIFaQ&c=3D5VD0RTtNlTh3ycd41b3MUw&r=
=3DyQ6uxs93kjlU9Af462nK3Q&m=3Ddz03e4mAYDpPawVhR85DRhsO2Nw6Y2H5aHTBpJ5da4I&s=
=3DlL4YtaX3aPybhI6TYN4dw5HEbE3g7qTWHreJZihwisI&e=3D
>>
>>There are a number of references listed there which may be helpful in you=
r write-up.
>>
>>Regards,
>>
>>- johnk
>>
>>
>>> On Apr 19, 2016, at 12:52 PM, Brad Hill <[email protected]> wrote:
>>>
>>> I've (at last) attempted to write a developer-friendly narrative explan=
ation of all of this stuff here.  How CORS works, the permission model, and=
 some of the historical reasoning behind the various choices.
>>>
>>> https://urldefense.proofpoint.com/v2/url?u=3Dhttps-3A__docs.google.com_=
document_d_1AtxTDw-2Dg9BSRW9n9kGTTqNkDTGcVfSKPAOjVGkPFu2k_edit-3Fusp-3Dshar=
ing&d=3DCwIFaQ&c=3D5VD0RTtNlTh3ycd41b3MUw&r=3DyQ6uxs93kjlU9Af462nK3Q&m=3Ddz=
03e4mAYDpPawVhR85DRhsO2Nw6Y2H5aHTBpJ5da4I&s=3Dtl0wJmbCveJ_j6dmuFSAV6OUKwAlv=
wRzokIkIPFuZLs&e=3D
>>>
>>> Yes, it's a Google doc for now since that was fastest for me to compose=
, but if people think it is useful, I can incorporate comments and maybe we=
 can turn it into a WebAppSec WG note or joint TAG finding.
>>>
>>> -Brad
>>>
>>>
>>>
>>> On 4/1/16, 11:26 AM, "Tim Berners-Lee" <[email protected]> wrote:
>>>
>>>> Thank you Jonas, for that clarification.
>>>> some response inline.
>>>>
>>>>> On 2016-01 -21, at 01:24, Jonas Sicking <[email protected]> wrote:
>>>>>
>>>>> On Mon, Jan 18, 2016 at 3:27 PM, Mark Nottingham <[email protected]> wrot=
e:
>>>>>> ... 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.
>>>>>
>>>>> I'm bummed to hear that aspects of CORS is still confusing even to th=
e
>>>>> 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..
>>>>
>>>>>
>>>>> 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.
>>>>>
>>>>> 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 informatio=
n
>>>>> 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 sen=
t
>>>>> to the target website.
>>>>>
>>>>> 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 expose=
d
>>>>> through the API which triggered the request.
>>>>>
>>>>> 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.
>>>>>
>>>>> 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.
>>>>>
>>>>> 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.
>>>>>
>>>>> Q: Why are security checks performed when withCredentials is set to f=
alse?
>>>>> 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.
>>>>>
>>>>> 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 publ=
ic 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
>>>> 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 a=
ny privilege access as a result.
>>>>
>>>> One possible but hard route is to pursue something like the router tel=
ling your machine whether it has no privileged access, which would then ena=
ble a lot of stuff.  So public internet spaces would set the flag, which wo=
uld then mean the browsers would do less preflights, wasted attempts to acc=
ess 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.
>>>>
>>>>>
>>>>> 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 resou=
rces on the site, and so in that case they ought to use that function to dr=
ive the headers automatically.  THAT is what should be coded up in the comm=
on servers.
>>>> That would help the server manager do the right thing.
>>>>
>>>>
>>>>>
>>>>> 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.
>>>>>
>>>>> 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.
>>>>>
>>>>> When crossdomain.xml was released many websites opted in allowing dat=
a
>>>>> to be read from other websites in order to share some public data tha=
t
>>>>> 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.
>>>>>
>>>>> 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.
>>>>>
>>>>> 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
>>>> shoot themselves in the foot coming from a non-optimal attitude.
>>>> To first order, the system must implement a security protocol which al=
lows
>>>> 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 whic=
h 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.
>>>> 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 CO=
RS 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.
>>>>>
>>>>> This doesn't account for static responses which are password protecte=
d
>>>>> using either cookies or auth headers. So yeah, our solution here is
>>>>> not perfect, but we decided to opt for simplicity.
>>>>>
>>>>> My personal hope was also that generic server modules would be writte=
n
>>>>> 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 t=
end to just defeat CORS
>>>> and they don=E2=80=99t necessarily distinguish between public resource=
s and others.
>>>>
>>>> Also people use CORS proxies to access the web, which are associated
>>>>
>>>>
>>>>> [...]
>>>>>
>>>>>
>>>>> 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 applic=
ation-level knowledge of which resources it is going to fetch are public, w=
hich are private.   So a general the fetch has to work without that hint, a=
nd do the right thing.
>>>>
>>>> b) For a webapp which needs to load stuff from the net, the lack of cl=
ear error conditions makes it hard to understand what is going on.    A goo=
d
>>>>
>>>> c) Asking server writers to do the origin reflection thing is unreason=
able
>>>>
>>>>
>>>>>
>>>>> 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.
>>>>>
>>>>> / Jonas
>>>>>
>>>>
>>>>
>>