- It has a name. That name was allowed to become more recognizable than that of the actual security mechanism (SOP).
- Once you use its name and start thinking of CORS as "the thing", most of DX is about CORS standing between you and perfectly reasonable, legitimate functionality you need to support.
- It does seem to put control in a weird place (backend telling a browser what it is or isn't allowed to do), and people seem to miss that this relies entirely on the browser itself being a compliant party you cannot control.
- I have my own, rather negative, opinions on the whole security model of the browser, that's strongly countercurrent (mostly about how it disenfranchises users), so let's just say here that this is indeed a hard problem being solved - so it doesn't help when people think of an exception policy as a security measure.
If you can run arbitrary code that can connect to other sites and make requests there someone will do that. And those calls can do exactly what they would on site. Only place to control this is the browser. Thus moving this decision to browser. One piece we probably trust way too much.
Live is simple when you directly communicate with one "server"(address) for one thing. Communicate with more. Well you never know if those others intended you to be able to do this.
And then when also all the authentication information lives in the browser too the mess is ready... So whole thing should have been build differently from start.
CORS is counter intuitive. I don’t think there is a better way to solve the problem, it is just a difficult to understand problem.
CORS errors occur when JavaScript in the browser attempts to call a server which is not configured to allow it. But the check is purely client-side. You can circumvent it entirely by using curl or whatever outside the browser.
For example the server sends a header indicating which domains it allows requests from, but it does not actually check if requests are from those domains. It is the responsibility of the client to check its domain is allowed.
All this make it seem like a pretty useless security feature, unless you understand the very specific kind of attack this protects aginst.
Example: I post “fungame.com” on Show HN, you visit it, and in the background the JavaScript calls Facebook on your behalf (using your Facebook authentication cookie) and adds me as friend.
By default such cross-domain requests from JavaScript are disallowed, but CORS allows it if the server specifically opt-in. But the check happen in the browser, since the purpose is to protect the user of the browser.
There are some weird exceptions to this, for example a client can always GET and POST data to another domain under certain constraints, since this have always been possible using HTML forms. So it is not obvious what is possible and what isnt.
> Example: I post “fungame.com” on Show HN, you visit it, and in the background the JavaScript calls Facebook on your behalf (using your Facebook authentication cookie) and adds me as friend.
Isn't that what CSRF protections are for, not CORS? There are other (very old) ways to trick a user into doing a POST that wouldn't be blocked by CORS -- and as you say, GET and some POST requests can always be sent but you don't see the response.
My understanding is that the actual protection that it gives in this scenario is that the "fungame.com" JavaScript cannot read your friends list or your list of private messages (basically, blocking GET data that should not be shared to random sites, as it would violate user privacy). You still need CSRF protections regardless of CORS.
Yes, the original CSRF attack using a plain html form does not even require JavaScript. CORS does not address this scenario.
But cross-domain post is only allowed if the payload is form data encoded. A Json payload from JavaScript would be blocked by default, as would other methods beyond get and post. Therefore you usually don’t have to worry about CSRF for a JavaScript API.
CORS is a a way to enable cross-domain calls from JavaScript without introducing the CSRF issue.
Is there a reason this has to happen client side with extra pre-flight requests? Taking your example, why couldn't Facebook's server just check the origin header and then reject all request from unapproved origins server side instead?
Servers certainly can (and probably should) check request origin. But it is not something they usually do, since cross-domain requests from JavaScript wasn’t possible before CORS.
If support for cross-domain request were introduced in browsers without requiring opt-in from servers, most sites would not be prepared against this new risk. It would open massive security issues across the web.
Your first sentence is the proof that CORS is a bad solution.
HN is supposed to be full of people who need to know, use and depend on CORS and CSP. We might all just be idiots, but we're the idiots who are supposed to use this tool, and we can't explain it or agree on it.
If a tool can't be used or understood by the primary users, IMO it's by definition a bad tool/solution. It's easy to see why - it's security that depends on a browser, something we're traditionally told never to depend on for security.
Even the HN comments here are a sea of confusion and contradiction.
It's stunning and makes me wonder whether CORS is a bad solution, or if it's solving a hard problem.
Problems:
- It has a name. That name was allowed to become more recognizable than that of the actual security mechanism (SOP).
- Once you use its name and start thinking of CORS as "the thing", most of DX is about CORS standing between you and perfectly reasonable, legitimate functionality you need to support.
- It does seem to put control in a weird place (backend telling a browser what it is or isn't allowed to do), and people seem to miss that this relies entirely on the browser itself being a compliant party you cannot control.
- I have my own, rather negative, opinions on the whole security model of the browser, that's strongly countercurrent (mostly about how it disenfranchises users), so let's just say here that this is indeed a hard problem being solved - so it doesn't help when people think of an exception policy as a security measure.
Fundamental mistake was to build web like we did.
If you can run arbitrary code that can connect to other sites and make requests there someone will do that. And those calls can do exactly what they would on site. Only place to control this is the browser. Thus moving this decision to browser. One piece we probably trust way too much.
Live is simple when you directly communicate with one "server"(address) for one thing. Communicate with more. Well you never know if those others intended you to be able to do this.
And then when also all the authentication information lives in the browser too the mess is ready... So whole thing should have been build differently from start.
CORS is counter intuitive. I don’t think there is a better way to solve the problem, it is just a difficult to understand problem.
CORS errors occur when JavaScript in the browser attempts to call a server which is not configured to allow it. But the check is purely client-side. You can circumvent it entirely by using curl or whatever outside the browser.
For example the server sends a header indicating which domains it allows requests from, but it does not actually check if requests are from those domains. It is the responsibility of the client to check its domain is allowed.
All this make it seem like a pretty useless security feature, unless you understand the very specific kind of attack this protects aginst.
Could you go the full mile and explain that very specific kind of attack?
Example: I post “fungame.com” on Show HN, you visit it, and in the background the JavaScript calls Facebook on your behalf (using your Facebook authentication cookie) and adds me as friend.
By default such cross-domain requests from JavaScript are disallowed, but CORS allows it if the server specifically opt-in. But the check happen in the browser, since the purpose is to protect the user of the browser.
There are some weird exceptions to this, for example a client can always GET and POST data to another domain under certain constraints, since this have always been possible using HTML forms. So it is not obvious what is possible and what isnt.
> Example: I post “fungame.com” on Show HN, you visit it, and in the background the JavaScript calls Facebook on your behalf (using your Facebook authentication cookie) and adds me as friend.
Isn't that what CSRF protections are for, not CORS? There are other (very old) ways to trick a user into doing a POST that wouldn't be blocked by CORS -- and as you say, GET and some POST requests can always be sent but you don't see the response.
My understanding is that the actual protection that it gives in this scenario is that the "fungame.com" JavaScript cannot read your friends list or your list of private messages (basically, blocking GET data that should not be shared to random sites, as it would violate user privacy). You still need CSRF protections regardless of CORS.
Yes, the original CSRF attack using a plain html form does not even require JavaScript. CORS does not address this scenario.
But cross-domain post is only allowed if the payload is form data encoded. A Json payload from JavaScript would be blocked by default, as would other methods beyond get and post. Therefore you usually don’t have to worry about CSRF for a JavaScript API.
CORS is a a way to enable cross-domain calls from JavaScript without introducing the CSRF issue.
> Isn't that what CSRF protections are for, not CORS?
Without the same origin policy CSRF protections would be trivial to circumvent, since you’d be able to read the CSRF token from any page.
Sure, but that falls under the "no unauthorised GET data" thing I talked about...?
Is there a reason this has to happen client side with extra pre-flight requests? Taking your example, why couldn't Facebook's server just check the origin header and then reject all request from unapproved origins server side instead?
It is the difference between opt-in and opt-out.
Servers certainly can (and probably should) check request origin. But it is not something they usually do, since cross-domain requests from JavaScript wasn’t possible before CORS.
If support for cross-domain request were introduced in browsers without requiring opt-in from servers, most sites would not be prepared against this new risk. It would open massive security issues across the web.
It’s mostly for backwards compatibility. Sites don’t always check the request origin, the browser SOP mitigates that problem on behalf of the user.
Your first sentence is the proof that CORS is a bad solution.
HN is supposed to be full of people who need to know, use and depend on CORS and CSP. We might all just be idiots, but we're the idiots who are supposed to use this tool, and we can't explain it or agree on it.
If a tool can't be used or understood by the primary users, IMO it's by definition a bad tool/solution. It's easy to see why - it's security that depends on a browser, something we're traditionally told never to depend on for security.