> The webserver listening in on localhost:19421 should implement a REST API and set a Access-Control-Allow-Origin header with the value https://zoom.us. This will ensure that only Javascript running on the zoom.us domain can talk to the localhost webserver.
No, that does not do that. JavaScript from any other website can still talk to localhost:19421 just the same. CORS doesn't restrict anything, it loosens the default set of restrictions (ignoring preflight requests for now and assuming we're talking just about "safe" Methods). That Access-Control-Allow-Origin header just allows JavaScript running on zoom.us to read the responses when it queries localhost:19421. The requests happen in any case, and you must ensure in your backend that they don't cause any adverse effects.
The article does a nice job giving a concrete example.
This is really oversimplifying things, incorrectly IMO, and that sentence makes it sound like you're confusing a CSRF vulnerability with CORS protections. Normally when you write a backend server you implement some sort of authentication and access control, and in that scenario the threat model that lets "an attacker gets one your users to take an action on your site by visiting their site" is a CSRF vulnerability, unrelated to CORS.
The scenario presented in TFA is actually a very special case, because the bug is with a webserver running on localhost that doesn't (apparently) implement access control - not something most web apps entail.
In fact, one of the parts that confuses a lot of people is that CORS rules only prevent the JavaScript web client from reading the response from a remote endpoint - if the endpoint is available on the public Internet then anyone can still make a request to it.
The other thing that is confusing about CORS is that browsers already let you load lots of resources from cross origin servers - you can load images (as TFA points out that Zoom did as a workaround), scripts, stylesheets, form submissions, etc. The one thing you can't do, unless the server implements the appropriate CORS headers, is make a cross origin fetch request from JavaScript.
CORS _additionally_ requires OPTIONS pre-flight to succeed, before allowing any kind of request outside of what can be achieved with a HTML form submit action. So it blocks PUT/PATCH/DELETE, specifying most Content-Type, and specifying nearly all other headers. But this is just blocking "non-standard complex requests that might confuse badly programmed pre-javascript-era servers".
It passes all standard requests that you could have made by: embedding the url as an image src, the target of a HTML form, endpoint for csp reports, etc. All still need to be checked methodically by the server for CSRF if it's going to take any mutating action due to the request.
It isn’t a knowledge thing (though it could be), or a capability thing, or intelligence. It’s pure mindset.
Ask yourself: is the average person noticing holes in fences and trying random doorknobs… probably not.
But on the other hand, most security people don’t think of product or UX (but some might) so that’s why you have roles.
CORS literally exists only against XSS and CSRF for actively logged in human users. Anything else in CORS is absolutely pointless because every other attack scenario uses scripts or programs that fake HTTP headers anyways. It's just as useless as the Sec-CH (client hint) headers because some Browser made by a company that starts with Micro and ends with Slop decided that the User Agent always needs to be Windows 10 for compatibility reasons.
That is why you see everyone just enabling every CORS option anyways, even though that is literally the worst case that allows XSS and CSRF. And a lot of websites have user edited content at some place, at the very least in images that aren't filtered for embedded scripts (PNGs, anyone?).
Client hints are useful for all the shitty “responsive” websites that don’t know how to use media queries. And for ad tracking. Mostly the latter
[1] https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/COR...
A CORS error is not "an error message sent to the browser", it is an error generated by the browser, because the browser has decided it cannot permit the request. (Though certainly a server can not understand a CORS request as such, and returned a weird response, which would then end up getting translated to a CORS failure.)
We easily form the intuition of the client being a by-default untrusted entity, and checking whether it has the privilege of accessing this data, where the server is the arbiter of that access.
CORS is so inherently different to that, and while the information is easily available, it requires a short but careful read to grok the idea -- which a dev tunnel-visioning towards getting their application code written may not wish to slow down for.
"So let me get this straight. We tell the client whether the application we gave them can or cannot make requests to our servers. And none of this actually prevents the client from making the requests if they want to?... Pull the other one it has bells on."
It took a good sleep and a long shower to under stand it. "Oh... it is for if I want to do a self injection attack and allow random untrusted malicious code in my application. In other words, ads"
Basically the threat model is inverted from any other threat model, that is why it looks so stupid. CORS is threat model used for when you can't trust your self.
- protocol itself is quite nuanced, like iirc requests with Authorization (or some other) headers don't obide by usual rules, and again for developer it's just an arbitrary convoluted set of rules, if they don't grasp the problematics
- backend and frontend should work in unison to have correctly configured cors, but as we know, devs hate communicating with each other
Many or most developers work on existing projects that have all kinds of security defaults set somewhere in the past and no one bothers reviewing those.
I log in to social.net. I click on scam.org and change sites. I'm on scam.org and it triggers a request to social.net/friends.
No cookies are sent, no JWT. I'm not logged in and get a "Needs login" HTTP error. Nothing bad happens.
I thought that's how it works without CORS already.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Coo...
You get results where it's really difficult intuitively understand it because at that point you're not really meant to. Realistically, people just follow a guide, or some lib, and move on.
I would also say I think Firefox's network inspector is better in this area. (But I'm often having to ask others to "no, don't send the failing request, send the CORS preflight", we need to understand what happened with it.)
> Anecdotally, lots of developers I’ve talked with don’t understand well how CORS works.
Yeah, most FE devs I've worked with seem to not understand CORS.
> Is the CORS API too complex and confusing
I think it can be hard if you don't understand why the exceptions to preflights are what they are, but the moment you internalize "because the browser can already emit that request in other cases" then it becomes obvious what categories are what & why.
contractors, "specialists", etc. who never took the time to read how CORS works and how simply you can handle a list of allowable sites, etc.
it's only complicated until you take the 5-10 minutes to properly understand what happens where. if you don't know, go do it now.
I'm saying this as someone who has learned about CORS protections many times, implemented the solutions with care they deserved, but forgot most of it soon after - each time. So I'd be very happy to invest even 15 minutes to break this cycle.
At least so long as they don't have malicious extensions or a non-CORS browser?
cors et al is a freaking mess because those things are designed by a comitee choke full of people who last promotion was their cool idea about how to monetize referrer, or how do cookie match across domains, or profile you with millisecond it takes to list your usb audio devices, or etc etc etc