One thing that confuses me about CORS is who it is trying to protect. I'd never really looked into it recently, as I'd never done anything that needed a cross origin request.

But recently I wanted to make a little web page that could control my Denon A/V receiver. The receiver has two or three different network APIs. There's one that uses telnet, and a couple of different HTTP ones.

You can point a browser at the receiver, and it gives you a page for controlling the receiver using one of the HTTP APIs. The API is reasonably fast, but the control page itself is glacial. A bit of poking around in the browser looking at requests and responses in the network monitor in the developer tools told me how to use that API.

The other HTTP API is used by the Denon mobile app. A bit of packet sniffing while using the mobile app told me how to use that API. Like the other HTTP API, that one is fast. The mobile app is also responsive, once it launches, but sometimes it takes a fair bit of time to find the receiver.

What I wanted was a simple web page, that I could stick on my website on Amazon Lightsail, which would just tell me the current source and volume, have buttons to switch between sources, and buttons for setting the volume. The page would use JavaScript to talk to the Denon.

Well, this was fine for changing inputs and volume, because those were simple GET requests. The Denon's web server doesn't implement CORS at all, so the responses lack any CORS headers, and the browser rejects them...but by that time the actual desired action has taken place on the server so I can just ignore the error.

For source and volume, that doesn't work because I need to get the returned data.

I flailed around for a while trying to find a way around this. Finally I ended up giving up on the original place of having my page on my outside website. Instead I stuck it on an RPi that is in my living room controlling a space heater and doing temperature monitoring, and put some server side code on the RPi to control the Denon. The page then invokes that code on the RPi to do the actual commands to the Denon. The web page is only interacting with the RPi, so no CORS worries.

I probably got a bad impression of CORS from all this, but I can't figure out what it actually helps. Lets say we have a site that came from site S, running on the browser of user U, and from there is trying to do a cross-origin request to site C.

It's not protecting C from anything I can see, because any restrictions C specifies in the CORS response headers depend on U honoring them to do anything. Someone trying to do something malicious with C could just ignore them.

It's not protecting U from scripts sending out personal information to C, because CORS doesn't block sending information if you do your sending in a way to not trigger the preflight check, which is easy to do. It just blocks your browser from doing anything with the response.

If a bad guy is able to get scripts to run U's browser for a site from S, it does block those scripts from getting data from C (unless C says it is OK). But if the bad guy really needs their script to get data from C, they could just go through an intermediate server they control that relays data from C. They control the CORS headers on their server, and can strip the CORS headers that come from C.

What am I missing?

PS: the Denon control page came out nice, I think [1] (well, except the centering of the "Recheck status" button looks off a bit...never noticed that before). It's all flexbox layout that resizes reasonable, so it is quite usable on my iPhone, iPad, Surface Pro 4, and iMac.

[1] https://imgur.com/3tIhXUE