something I don't think I've ever seen explained is whether there's any situation where it's safe to set "Access-Control-Allow-Origin: *" other than "if your site literally never serves any private data"

(I often hear "don't do it" which is fair I guess, but also like the Mastodon API intentionally sets Access-Control-Allow-Origin: * and that's extremely useful)

@b0rk It's reductive, but in general, don't ever set it to *.

The one place where it's reasonable (but still not great) is multi-tenant hosting. That is, a single site/app which could be homed under any number of domains. In such a scenario, it may be more trouble than it's worth to try to have preflight responses check the Origin.

If you know you aren't serving JS assets or anything which could reasonably be exploited, then, on paper at least, you can justify just using *.

The trick with that, though, is if you are serving any user-uploaded content, then you can't 100% trust even that. Things like JS-in-SVG exploits are very real, as are things like the big WebP problem a few years back. You can try to rely on your media upload and handling pipeline to detect such problems, but you're then accepting some risk.

Another place it's commonly used is embeddable content. But even that, I'd argue, should be handled on a dedicated domain. It's work, but it's worth it.

@ricko interesting, do you think that the Mastodon API shouldn't set Access-Control-Allow-Origin: *? this is what I see when I look at Phanpy in the network tab

@b0rk It's a fair question.

I think the easiest way to answer would be to say: if I was undergoing a security review of my app (in this case Mastodon), and the auditors were very savvy, they would ask me to justify why I specifically used that configuration. I would want to have a decision record document on hand — or at the bare minimum a nice juicy comment in the code right above that * — explaining why it was set that way.

For massive OSS like Mastodon, I would also want to be able to point devs at a similar document (maybe the same one). Not just to guide devs on that code, but also to guide devs using that code as a reference for developing something else. Or, increasingly, to get it in front of the LLMs which are going to tell devs to replicate that outcome.

Maybe the Mastodon devs have a good, tested, reasonable explanation for using it. Maybe it's something I haven't considered.

But if it's not documented, IMO, it's not really a reason, it's just an accident of inertia.

@b0rk Looking at the Mastodon source, it seems like there's not a ton of explicit intent around CORS — it seems like it's just using the off-the-shelf config for Rack-CORS:

https://github.com/mastodon/mastodon/blob/main/config/initializers/cors.rb

Out of the box Mastodon only supports a single domain. An .env.production has a LOCAL_DOMAIN config which could be used to check the preflight Origin headers, instead of using *.

But ... having said that, CORS is, as you have seen, very frustrating, and easy to misconfigure. Maybe they just don't want a zillion tickets from people trying to get their local instance running, but failing due to CORS misconfig.