Whenever your browser sends any request to any site, it sends the cookies(/other auth data) associated with that site along with it. In other words, cookies are fundamentally just associated with the receiver, not the sender. So the "solution" is for the receiver to block requests from the wrong sender, since otherwise any site could send authenticated requests to any random site. [Edit in response to comment below: I should've mentioned more here, but I understand what happened was browsers introduced the Same-Origin Policy to prevent this from happening, and introduced CORS as a dynamic bypass mechanism for that, which, unless you implement OPTIONS, can get you these half-baked insecure situations where requests still get sent and executed, but the client JS doesn't get to see the responses.]
To me this whole mess is stupid because the premise shouldn't be true in the first place (why the heck should a cross-origin request send auth data? cookies etc. should be "contained" to whatever domains the original site restricted them to), but that's apparently The Way Things Are, and so here we are: browsers do something completely unexpected and insecure, and we blame devs for getting caught off-guard and not protecting against a security hole browsers introduce.
(Yes, I have Opinions on this. Please tell me exactly where I'm wrong, because I suspect I might be, but I have yet to figure it out.)
(P.S. the way you phrased the request handling would violate causality, so I'm assuming you were referring to the OPTIONS check beforehand...)
I'll admit I may be one of the developers that doesn't understand CORS...
CORS was introduced as a way to allow requests that browsers used to not allow at all: things like cross-site XHR in the first instance. Then it was expanded so that requests that are not normally subject to CORS checks (image loads, script loads, stylesheet loads) could opt-in to being subject to them, for various reasons. The default for those loads is still "no CORS". And there still isn't a way to do a navigation subject to a CORS check, even with opt-in.
Disclaimer: I work on Gecko and I've reviewed/implemented parts of the CORS spec.
There's a second problem CORS kinda tries to solve, which is the ambient authority problem: services that run behind firewalls and assume that if someone can reach them the someone should have access. If someone runs a browser behind the firewall and opens a page on unsafe side of the firewall, that page can then issue network requests from the browser and thus end up access things on the "safe" side of the firewall. This is a large part of why CORS has the whole preflight complication and the rules around when preflights happen: the idea is that in this situation just making the request, not even receiving a response, is potentially damaging. There are the carve-outs for requests that could be generated without things like XHR that are subject to CORS (e.g. by doing a form submission or <img> load or whatnot); if your ambient-authority-using server responds in interesting ways to those, CORS is not going to help you... The _right_ fix for this stuff, of course, is for services to stop using ambient authority and/or for browsers to block requests from public sites to private IPs. Unfortunately in practice detecting "private IPs" reliably is not trivial, because fundamentally it depends on the routing and firewall topology, which the browser doesn't really know about.
> The NoScript extension for Firefox includes ABE, a firewall-like feature inside the browser which in its default configuration prevents attacks on the local network by preventing external webpages from accessing local IP addresses.
They do block certain ports that are known to be problematic (25, 6667, 5222, etc)
I haven't been following this closely, but for Firefox https://bugzilla.mozilla.org/show_bug.cgi?id=354493 is the relevant bug, with some (failed) attempts to do that.
This is why we have CSRF tokens. So that you can effectively block Cross-Origin writes.
But yeah, you can't just make arbitrary requests like this with XHR
If you just create an HTML form with the bank as action, fill in the inputs and submit via JS, no, because that's _navigating away_. This is also why GET requests that perform actions are dangerous, you can just embed them as an image to provoke a request. Which is exactly how zoom built their API. (they also then measured the size of the image to determine the response code, which is.... inventive)
Before the client does the request for data, it does a preflight request via OPTIONS to determine what is allowable (is this domain allowed, this type of call).
If it is allowed, it can send and request cookies on the requested domain in the current standard.
However, this is not supported in older browsers, so the request will just work.
In newer browsers, without the preflight check, the server still receives and replies to the request, but the reply is ‘ignored’ by the browser and throws an error.
The server still sees the request, so the data can be exfiltrated.
In terms of backwards compatibility, it is actually the opposite. Newer browsers will block stuff that worked in older versions.
(as you mentioned, backwards compatibility requires that this is opt-in when the cookie is set, not opt-out)
for ( x = 1; x < 10000; x++ )
load_page(https://facebook.com/newpost?to=world&message="My mother's face resembles an unwashed buttocks");
By default, the same-origin-policy doesn't allow all requests to other origins (domains/websites/ports). But if you want to allow another website to send requests to your site you can use CORS to do so.
So for example, if you have a contact form on one page (example.com) and the API for processing the submitted forms on another domain (processing.com; different origin), the receiving server tells the browsers via CORS that submissions from example.com are allowed.
It can still be abused to exfiltrate data.
So, the one domain will attempt to communicate, the other domain will receive the request and return a response.
If the client doesn’t ‘like’ the response, it will error.
So in fact CORS without any server-side configuration allows one to do arbitrary GET requests with cookies and authentication through XHR, but you could always just dynamically create IMG (as in the Zoom kludge) or SCRIPT (and the response will be executed in the page context, which is huge security risk as well as how JSON-P works) tag.
In other words: if your application does something security-sensitive (ie. write to anything other than log file) as part of GET request apart from producing the response, then your application is broken and same-origin policy nor CORS has nothing to do with that.