This had always been true; making cross-origin requests with e.g. <img> tags is still very much a thing.
This had always been true; making cross-origin requests with e.g. <img> tags is still very much a thing.
Apparently, since developers should already have been protecting against cross-origin requests on GET and POST via other means (CSRF tokens), there was no need for the additional preflight protection.
They only added preflights to requests that browsers couldn't make previously.
Thats the threat model CORS is meant to address. Not just in general that a web host might not want a request from "anywhere" happening, but that site B might not want an authenticated request on behalf of User X to site B being made by code from site A.
You're right that sending cookies is the problem CORS addresses, but XmlHttpRequest didn't break any assumptions that were valid before.
I didn't say that XmlHttpRequests "broke any assumptions that were valid before", I don't know exactly what that means.
If an XmlHttpRequest were allowed to do arbitrary cross-site requests, Javascrpt could use them do some of the kind of attacks mentioned above. Which is why XmlHttpRequests can't do cross-site requests. CORS exists to let XmlHttpRequests do cross-site requests only in an opt-in way, so a site can opt-in to it in ways that it knows/believes are secure from attacks like above.
I'm not saying the overall web security story is perfect (nobody would ever say that!), but that's where CORS comes from, and why it's different than img tag.
The common misconception is that CORS exists as some kind of general access control to your website. It only exists to keep the user of a well-behaved browser safe (in certain ways) from malicious Javascript on a site they are visiting. CORS has nothing at all to do with any scenarios involving malicious browsers, which are of course free to ignore CORS.
Well, "proper implementation" would prevent a lot of attacks. But there's nothing stopping you, as a web server, from making state changes in response to GET requests, and it's far from unheard of.
1) POST.
2) Of arbitrary content.
3) With an arbitrary Content-Type header.
You don't get an OPTIONS for the sort of XHR request that you could do with an <img> tag (always GET). You don't get an OPTIONS for the sort of XHR request that you could do with a <form> tag (GET or POST). You only get OPTIONS if one of the following is true:
* Your request method is not GET/HEAD/POST
* You set a header value for a header other than Accept, Accept-Language, Content-Language, or Content-Type.
* You set Content-Type to a value other than "application/x-www-form-urlencoded", "multipart/form-data", or "text/plain".
* You have upload listeners on the XHR upload.
* You use ReadableStream in the request.
No way for JS to do that with an IMG tag, I don't think.