When should I really set "Access-Control-Allow-Credentials" to "true" in my response headers?
Allow-Credentials would be needed if you want the request to also be able to send cookies. If you needed to authorize the incoming request, based off a session ID cookie would be a common reason.
Setting a wildcard allows any site to make requests to your endpoint. Setting allow to origin is common if the request matches a whitelist you've defined. Some browsers will cache the allow response, and if you requested the same content from another domain as well, this could cause the request to be denied.
Setting Access-Control-Allow-Credentials: true
actually has two effects:
- Causes the browser to actually allow your frontend JavaScript code to access the response if credentials are included
- Causes any
Set-Cookie
response header to actually have the effect of setting a cookie (theSet-Cookie
response header is otherwise ignored)
Those effects combine with the effect that setting XMLHttpRequest.withCredentials
or credentials: 'include'
(Fetch API) have of causing credentials (HTTP cookies, TLS client certificates, and authentication entries) to actually be included as part of the request.
https://fetch.spec.whatwg.org/#example-cors-with-credentials in the Fetch spec has a nice example
Why should I set
Access-Control-Allow-Origin
toorigin
obtained from request header rather than wildcard*
?
You shouldn’t unless you’re very certain what you’re doing.
It’s actually safe to do if:
- The resource for which you’re setting the response headers that way is a public site or API endpoint intended to be accessible by everyone, and
- You’re just not setting cookies that could enable an attacker to get access to sensitive information or confidential data.
For example, if your server code is just setting cookies just for the purpose of saving application state or session state as a convenience to your users, then there’s no risk in taking the value of the Origin
request header and reflecting/echoing it back in the Access-Control-Allow-Origin
value while also sending the Access-Control-Allow-Credentials: true
response header.
On the other hand, if the cookies you’re setting expose sensitive information or confidential data, then unless you’re really certain you have things otherwise locked down (somehow…) you really want to avoid reflecting the Origin
back in the Access-Control-Allow-Origin
value (without checking it on the server side) while also sending Access-Control-Allow-Credentials: true
.
If you do that, you’re potentially exposing sensitive information or confidential data in way that could allow malicious attackers to get to it. For an explanation of the risks, read the following:
- https://web-in-security.blogspot.jp/2017/07/cors-misconfigurations-on-large-scale.html
- http://blog.portswigger.net/2016/10/exploiting-cors-misconfigurations-for.html
And if the resource you’re sending the CORS headers for is not a public site or API endpoint intended to be accessible by everyone but is instead inside an intranet or otherwise behind some IP-address-restricted firewall, then you definitely really want to avoid combining Access-Control-Allow-Origin
-reflects-Origin
and Access-Control-Allow-Credentials: true
. (In the intranet case you almost always want to only be allowing specific hardcoded/whitelisted origins.)