> 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.
[1] https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/COR...
The article does a nice job giving a concrete example.
Example: SOP stops example.com from fetching the list of subscriptions on youtube.com. But CORS allows example.com to access youtube.com/public/*.
This is also not the sole use-case, it also stops your backend api being up under a different frontend which would allow data theft since you could log into real services on google.com, but you're actually on g00gle.com enabling data exfiltration because now every request can be MitM'd.
If you find CORS difficult to understand, particularly the question of "why do we need this?", I suggest starting here: https://developer.mozilla.org/en-US/docs/Web/Security/Defens...
I've tried using the Same Origin Policy as an interview question in the past, but it's not a good question because the majority of candidates aren't familiar with it, so you learn very little by bringing it up.
> So what would a secure implementation of this feature look like? 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.
First of all, its not CORS that protects. CORS is an anti-security feature. What does protect is the SOP (same origin policy). The SOP (or SOPs rather, it's not really one feature but more of a paradigm in the standards) blocks documents from one origin, from reading data that belongs to another origin. This is the reason why `let w = window.open("https://example.com"); console.dir(w.document.body);` will work when it is ran from example.com, but not wikipedia.org. Only when protocol, host and port match, can documents access each others data (there is an interesting differential with cookies here, their SOP only looks at protocol and host, not port).
Importantly, the SOP only blocks reading data from other origins, not writing! So while example.com won't be able to read the response of a post request it sends to wikipedia.org, the request is sent and processed nontheless!
CORS now is a feature that allows sites to loosen up the SOP. This allows documents to read cross origin data nontheless. Namely, HTTP responses. (Standards for reading other kinds of data cross origin exist, but are not related to CORS).
What I still don't understand is what purpose the Access-Control-Allow-Headers header serves. It doesn't seem like it improves security for the browser (and definitely not for the server). Was it included "just for completeness" by the protocol designers? See also https://stackoverflow.com/questions/17992042
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.
- 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
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.
I wonder if much of that misunderstanding comes from the threat model being quite unusual and not always easy to understand.
For starters, there are three parties, which all don't trust each other: The server, the browser and the JavaScript running inside the browser.
The browser is supposed to protect the server against requests from unauthorized JavaScript applications. CORS is there to mark certain requests as "authorized", while keeping the protection active for the rest.
But the entire system only works if those three components exist in the first place, as enforcement is solely relying on the browser.
Most of us I think just "expose a set of whitelisted origins and be done with it".
Here is where I landed for how to specify your server's CORS policy:
Count me in!
Once you understand that it's onlying to solve problems that happen in a user's compliant browser, and not some wider issue of resource authorisation, it does get a bit easier to understand.
Though in a way CORS seems too simple for what it achieves.
Of course, that can't be undone now but I think the original-ish sin was when forms suddenly could perform _both_ cross origin requests _and_ get the ambient authority treatment (i.e. send the user cookies with the request though to be fair, basic auth + forms also enabled similar attacks even before cookies were introduced in the mid 90's).
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.
access is provided under condition you respect these restrictions
You are not obliged to honour this. It is not enforceable so it seems strange.
Browsers enforce it, but it can be turned off and nobody expects it to be implemented by a simple REST client application.
It’s a gentleman’s agreement. It’s a statement of expectation to the browser. On the one hand it may be for the protection of the browser user, from cross site attacks, and from malicious code on the web.
But crucially it provides little protection for the endpoints themselves bar accidental misuse.
It is very unusual and rare example of “cooperative” security in a web that’s frequently so adversarial.
And that’s what makes it hard to grasp.
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.
It’s confusing because unlike most security features, it’s meant to protect the users from themselves. The risk comes from a combination of users being allowed to visit malevolent sites and browsers letting all websites do a lot of random stuff, including making 3rd party requests with cookies and private stuff
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.
it's quite difficult to get your stack to work for local dev, CI, and prod since each most likely needs different cors headers. Especially if you use tunnels and proxies like we do.
What made it click for me though was understanding what problem it solved.
Developers don't understand CORS - https://news.ycombinator.com/item?id=20404578 - July 2019 (355 comments)
Who decided this was a developer's responsibility?
Yes
TL;DR: It's a restriction your browser gives itself. If it's on Domain A and it sees a request going out to Domain B, unless Domain B responds saying that it's expecting traffic from Domain A, the browser prevents itself from making the call.
I think the part about it that is off/silly to most people is that it's not a normal security threat model, because a malicious client could simply just...not impose that restriction on itself. You're perfectly capable of going and curling that same request to that backend, or calling it from an app, or any number of other things. So it's not really protecting your protected resource, the backend, from malicious clients.
All of that is where I feel like I understand clearly. The part I fail to retain is the exact scenarios it does protect against, which IIRC, are basically about attempting to protect your users from being misguided on other clients that are acting as your client, something like that (but again, this literally only applies to browsers). It's just kind of a weird niche problem that I often find myself thinking "I mean why is the user on another client and have allowed themselves to authenticate on that client with my server...this sounds like the user's fault."
It's truly confusing to see businesses with real PII, financial, and technical risks choose not to simply disable java for all websites on work systems' browsers; bake settings and other restrictions into immutable VM templates. From these run ephemoral/disposable, per-application suite VM's to enable the office workers to use the tools required for their jobs.
If a worker wants user-upload and FB utility they are free to use their own devices (phones) when they are on break.
If a role has specific need for a specific site that requires special refinements/relaxation or the security policies then that can have it's own templateVM and this allows granular control of which VM instances have access to which other instances' clipboard and if it is one-way or bi-directional.
These techniques aren't novel, aren't actually that difficult, and are actually in-use in many workplaces. Even on legacy systems this has been possible with Windows environments which require full Office utility - since the XP era with 'Embedded' tools like WindowsCE <~ not the best way to do it, but I have seen it done at scale by multinational enterprises.
Every reboot spawns a completely clean; custom configured clone of the 'official' image; and if too much changes - that clone evaporates and restarts from read-only image.
All the rest of this ''back-end, front-end, let some people in, keep others out, filter by structure but not by content,'' ... it's just such an exhausting topic to even read about, and i wonder what kind of kool-aid everyone drinks to get them to pretend any of that is actually for any purpose than to allow FAANG/MANGOS/SPAM tech-bro cults to suck up all the user activity meta+data from the free garbage they are peddling.
I need either more coffee, or less Uisge beatha bhon Hosh.
https://news.ycombinator.com/item?id=48616086
The whole thread shows that It seems even highly technical people that supposedly know a lot about this shit get it wrong. Because the mechanics are so complex, nobody really knows how they really work. Or it is a freaking mess or chore to achieve something.
Similar to just making a website HTTPS... even with let's encrypt and certbot , why does making a site https have to be so hard? (Try it on a service within a vpn).
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.
Its one of those situations where you need to think like an attacker to see the whole picture.
"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.
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