32

This question has been asked on here before and given an array of good answers, mainly: Access-Control-Allow-Origin Multiple Origin Domains?

However there seems to be a gap in explanation in terms of the approved method that should be undertaken. Reading through the W3 documentation we have what appears to me to be a conflict of guidance.

Firstly we see the answer given as the right way to do it in a lot of the previous answers which dictates that the host server must dynamically echo back the the given 'Origin' if it appears on a predefined 'whitelist'. http://www.w3.org/TR/cors/#resource-implementation

However a lot of the answers and methods used also allude to a space delimited list which can also be used as a method of passing multiple 'Origins' to allow. If we take a look at another piece of W3 documentation at http://www.w3.org/wiki/CORS_Enabled we see an example of this in the first section of the page as:

 Access-Control-Allow-Origin: http://example.com:8080 http://blah.example.com http://foo.example.com

Of these two methods I would be equally happy to incorparate either however there may be a large list of URLs which will need to be whilelisted and so I wanted to ensure that I am doing this corrently first time round. If anyone has any insight into the two methods mentioned above I would be very grateful to hear the decision in your choices and if there is a definitive guide to the recommended method I may have missed.

Community
  • 1
  • 1
JonnyIrving
  • 746
  • 2
  • 7
  • 17

2 Answers2

45

The documentation on this seems to imply that it allows multiple origins with a space separated list, but that's not what it actually means. Here's what I could gather as the most definitive answer to your question: the Access-Control-Allow-Origin header should be the same value as the Origin header as long as you want to allow it.

The reason it's not a whitelist that you send back to the client is because technically the client can send a space separated list of origins so that the server can validate the request. The purpose of origin list then is because the request could've come from multiple origins (ie. the request was redirected across domains). A test suite makes it easy to observe this behavior with varying redirect possibilities, even though a space separated list is never generated (by Firefox at least).

This is illustrated lower in the first linked W3C document you provided:

The Access-Control-Allow-Origin header indicates whether a resource can be shared based by returning the value of the Origin request header, "*", or "null" in the response. ABNF:

Access-Control-Allow-Origin = "Access-Control-Allow-Origin" ":" origin-list-or-null | "*"

In practice the origin-list-or-null production is more constrained. Rather than allowing a space-separated list of origins, it is either a single origin or the string "null".

And again in the definition of the origin list. In addition it shows if you do want to allow the string "null" as an origin, it wouldn't be able to be embedded in an origin list anyways.

So stick with the dynamically generated header based on the client's Origin header and whether that matches your whitelist.

Pluto
  • 2,525
  • 22
  • 31
  • 2
    Are there any security ramifications considering the client's origin header could be manipulated by the client? – wayofthefuture Sep 19 '15 at 11:32
  • 2
    The origin header is meant to protect a user from malicious websites. For example if mywebsite.com sent an AJAX request to mybank.com, it should be declined by default. If a user wants to modify this behavior though, then they could certainly do whatever they want. Users can easily open up their browser console, send requests to that website, and use the response for whatever other page they have open. Any HTTP-complying web browser won't let a website automatically do this though. – Pluto Mar 09 '16 at 17:02
  • 1
    Does anybody know, how do I validate a list of origins provided by a client? Should all entries match allowed domains list or at least one? – Sergey Mashkov Jun 24 '16 at 16:16
  • According to spec 6.2.2 user agent should never produce multiple origins at least for flight request: "The Origin header can only contain a single origin as the user agent will not follow redirects." – Sergey Mashkov Jun 24 '16 at 16:18
  • @SergeyMashkov It's better safe than sorry; you might as well verify the whole list. It seems like the origin list is so uncommon that it's almost always a single origin. If you run into any issues then you can look into adding other origins allowed or changing the behavior. – Pluto Jun 02 '17 at 16:52
0

If you need to allow a origin which contains a specific word "example" you may use the following configuration in your apache vhost.

SetEnvIf Origin "^((?:https?:\/\/)?(?:[^@\n]+@)?(?:www.)?.example?.*)" REFERER=$0 
Header always set Access-Control-Allow-Origin %{REFERER}e env=REFERER

This will satisfy some of the following Origin conditions:

http://abc.bcd.example.com
https://www.example.in 
http://abcdexample.com 
many more

You may tweak the above regex as per your requirement.

NightOwl888
  • 51,095
  • 20
  • 122
  • 194
  • 1
    This regex needs work... It doesn't match any of the examples you provided yet it matches things like `lexampl.lol`. Periods need to be escaped if you want to explicitly match periods, some sort of wildcard or character class needs to be used if you want to match subdomains (plus asterisk outside the grouping), and you should probably be explicit about which TLDs you want to match. – Pluto Jan 20 '20 at 20:49