CORS in few wors
Cross-origin resource sharing (CORS) allows scripts in third-party web applications to access resources in a domain.
Why is it needed?
Due to the same-origin policy (SOP) it isn't possible for a web application to request resources hosted in another web application using a script (SOP doesn't apply to CSS or images). CORS allows to soften this restriction.
What's an origin?
An origin is protocol+domain+port: https://example.tredecimal.com:443 if any of the three isn't exactly the same it isn't considered the same origin, subdomains are also considered a different origin (due to the domain changing). The origin is sent as a header on requests.
How does it work?
The client browser sends a GET request with the extra Origin header, if the server allows CORS, it returns an Access-Control-Allow-Origin header containing either the URL of the origin or a wildcard (if all origins are allowed). It can also return a Access-Control-Allow-Credentials if access to private parts is needed, this header will allow cookies, TLS user certs or authorization headers to be used.
What problems does it have
- It is not possible to define more than one origin per CORS endpoint.
- You can use different domains/origins for different endpoints of your application but not multiple domains for the same endpoint.
- You cannot use the
Allow-Credentialsheader when the wildcard is used in theAllow-Originheader. Due to the above restrictions, programmers and frameworks have found ways to allow multiple origins/domains to access the same endpoint while being able to use theAllow-Credentialsheader.
How can CORS be used while allowing multiple origins?
There are two ways, an insecure one, using the null Origin and an error-prone one using "dynamic origin validation".
Null is a special case of the "one domain" case. All origins can simulate being null (using a sandboxed iframe or a data-URL among other ways) and due to it falling into the "one domain" case it allows using the Allow-Credentials header. That has security implications. If anyone can fake a null origin, that means an attacker can too. In a way, it's like a more insecure wildcard.
Dynamic origin validation when correctly implemented can be both useful and secure. It's recommended to have a whitelist of fully qualified origins and compare the incoming Origin to them byte-for-byte . Using regex or matching only the beginning or end of the origin is very error-prone, can cause a security risk and should be avoided.
Of course it would be better if the specification simply allowed multiple domains in a secure way so each framework wouldn't need to write their own dynamic origin validation.
Misc
- Using the
vary: Originheader is a good idea when the response depends on the requester. When you use a CDN or something that can cache the response it avoids caching that. - Requests apart from GET and POST will get pre-flight.