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 (the Set-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 to origin 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:

  1. 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
  2. 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.)