We had a requirement to permit cross-origin requests provided that the origin was part of the corporate domain. While this question is not C# or Web API specific, the snippets below demonstrate our strategy.
We have a collection of regular expressions defining permitted origins:
private static readonly Regex[] AllowedOriginPatterns = new[]
{
new Regex(@"https?://\w[\w\-\.]*\.company.com",
RegexOptions.Compiled | RegexOptions.IgnoreCase)
};
Later, in our ICorsPolicyProvider
attribute, we test the origin. If the origin matches any pattern, we add the origin to the set of allowed origins:
var requestOrigin = request.GetCorsRequestContext().Origin;
if (!string.IsNullOrWhiteSpace(requestOrigin) &&
AllowedOriginPatterns.Any(pattern => pattern.IsMatch(requestOrigin)))
{
policy.Origins.Add(requestOrigin);
}
The perk of this approach is that we can support a large and flexible set of authorized origins, and restrict unauthorized origins, all without placing hundreds of origins in our headers.
We have an issue with HTTP header rewriting on the part of our reverse proxy. Under some circumstances, the reverse proxy replaces the Access-Control-Allow-Origin
value with the host. Seems fishy to me, but that is not my question.
It was proposed that we change our code so that if the origin meets our precondition that we return *
instead of echoing the origin in the response.
My question is whether we open a potential security vulnerability by returning Access-Control-Allow-Origin: *
to origins that match our preconditions. I would hope that browsers check the access control headers with every request. If so, I am not overly concerned. If not, I can imagine an attacker running an untrusted web site taking advantage of browsers that have previously received a *
for a trusted origin.
I have read the OWASP article on scrutinizing CORS headers. The article does not reflect any of my concerns, which is reassuring; however, I wanted to inquire of the community before pressing forward.
Update
As it would turn out, this question is not valid. We discovered, after exploring this implementation, that allowing all origins for credentialed requests is disallowed. After troubleshooting our failed implementation, I found two small statements that make this quite clear.
From the W3C Recommendation, Section 6.1:
Note: The string "*" cannot be used for a resource that supports credentials.
From the Mozilla Developer Network:
Important note: when responding to a credentialed request, server must specify a domain, and cannot use wild carding.
This proved ultimately disappointing in our implementation; however, I imagine the complexity of adequately securing credentialed CORS requests would explain why this is a prohibited scenario.
I appreciate all assistance and consideration rendered.