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.
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?
> 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.