CORS – Understanding Cross Origin Resource Sharing

corscross-domainjavascriptjquery

From what I understand about CORS, this is how it works: I have a site foo.com which serves a page X. X wants to post data to another domain bar.com. If bar.com is CORS enabled (its headers produce Access-Control-Allow-Origin foo.com) then page X can now send data to bar.com.

As I understand to get CORS to work it's all about settingit up on bar.com, and has nothing to do with foo.com. It's all about making sure bar.com doesn't accept requests from any old domain.

However this really doesn't make sense to me. I thought CORS was designed to enable foo.com to dictate who X is allowed to communicate with. If we go back to the previous example but this time X is compromised by dodgy script so that it sends data secretly to evil.com, how is CORS going to stop that? evil.com is CORS enabled, and set to *, so it will accept requests from anything. That way a user thinking they using a site foo.com, are unwittingly sending data to evil.com.

If it is really all about bar.com protecting itself, then why does it make the browser enforce the policy?. The only conceivable situation in which this makes sense if you have evil.com serving up page Y that impersonates foo.com, that tries to send data to bar.com. But CORS is enforced by the browser, all you'd have to do is make evil.com a proxy that sends faked origin requests to bar.com (data goes from Y to evil.com, evil.com sets its fake origin to foo.com then sends it to bar.com).

It only makes sense to me if it works the other way round. foo.com is CORS enabled, and its headers are set to Access-Control-Allow-Origin bar.com. That way rouge scripts would get denied access evil.com by the browser. It then makes sense for the browser to enforce the policy because its running the scripts that could go rouge. It won't stop rouge sites from trying to send rouge data to bar.com, but bar.com can protect itself with a username/password. If foo.com has endpoints that it's expecting data back from X, then you can embed tokens into X, to ensure evil.com doesn't send data to it instead.

I feel like I'm not understanding something fundamentally important here. Would really appreciate the help.

Best Answer

However this really doesn't make sense to me. I thought CORS was designed to enable foo.com to dictate who X is allowed to communicate with.

No, it's about bar.com controlling use of its content.

But CORS is enforced by the browser, all you'd have to do is make evil.com a proxy that sends faked origin requests to bar.com...

Yup. And if you do, and the people at bar.com notice and care, they disallow requests from your server. You move it, they disallow the new one. Whack-a-mole time. But painful as that game of whack-a-mole is, it's a lot less painful than if the requests come directly from each individual user of foo.com, from their desktop.

Having foo.com enforce what foo.com can do doesn't make any sense. foo.com already enforces what foo.com can do, because it's foo.com that serves foo.com's content and scripts.

Related Question