I have a mostly public API with some parts of it “credentialed” behind cookies, similarly to e.g. how WordPress’ REST API works. (In our case, it’s a GraphQL API but that shouldn’t matter.)
I want to enable CORS for it and am considering two options:
Access-Control-Allow-Origin: <dynamically return the incoming `Origin` header> Access-Control-Allow-Credentials: true
(Plus other headers like
Access-Control-Allow-Methods in both cases.)
https://evil.com, all should be OK:
Access-Control-Allow-Origin: https://evil.com Access-Control-Allow-Credentials: true
There’s no real problem – the evil site will be able to read the public parts of the API (which they can already do via
curl, for example) but they won’t be able to abuse a browser of a specific user that would be “logged in” to the API – cookies for our “site” will not be sent.
WordPress also uses Option 1 (for many years) and it’s secure enough – see e.g. this Trac ticket.
Still, I wonder why not use a wildcard – it’s simpler code (no need to dynamically read the
Origin header), no need to worry about setting related headers properly (
Vary: Origin) etc. The wildcard just seems simpler.
So my question is, why would I choose Option 1 for our API? What useful scenario does it unlock that wildcard prevents?