Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Access-Control-Allow-Origin is returned only if Origin header is set #24

Open
monfresh opened this issue May 31, 2013 · 8 comments
Open

Comments

@monfresh
Copy link

Rails 3.2.13, Ruby 2.0.0, Mongoid
config/application.rb:

...
config.middleware.use Rack::Cors do
      allow do
        origins '*'
        # location of your API
        resource '/api/*', :headers => :any, :methods => [:get, :post, :options, :put]
      end
    end

Using HTTPie:

http -h http://localhost:8080/api/organizations

Access-Control-Allow-Origin is NOT returned

If I set an Origin header:

http -h http://localhost:8080/api/organizations Origin:http://ohanapi.org

I get:

Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT
Access-Control-Allow-Origin: http://ohanapi.org

Is this expected? I was under the impression that Access-Control-Allow-Origin would be set to * even if no Origin was specified.

GitHub's API returns * when no Origin is specified. How can I get that behavior as well?

@schorsch
Copy link

schorsch commented Jun 5, 2013

+1

@aiwilliams
Copy link

I wonder what role this plays: http://www.w3.org/TR/access-control/#resource-implementation

@cyu
Copy link
Owner

cyu commented Jul 16, 2013

It think the current implementation is the correct behavior. Step one of the CORS spec states that any simple request without an Origin header is outside the scope of the CORS specification. (http://www.w3.org/TR/access-control/#resource-requests)

Having said that, I'm don't see any harm in possibly supporting this as an additional configuration (I'd like the default implementation to eventually match spec as much as possible).

Sorry for taking so long to respond to this. Is there a particular use case where this behavior is necessary? I'd like to understand under what circumstances why this behavior is desired.

@aiwilliams
Copy link

I agree the library should strictly implement the CORS specification.

It is interesting to note that responses from api.github.com have this header combination:

Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *

Reading the spec here, you'll find this Note in the discussion about supports credentials:

The string "*" cannot be used (as the value of the Access-Control-Allow-Origin header) for a resource that supports credentials.

My concern is further expressed in the discussion about Security Concerns. Namely, if a resource supports credentials, it should also reflect the requesting Origin as the Access-Control-Allow-Origin.

In other words, I think rack-cors has this right. Therefore, it should be difficult to do it wrong?

@snikch
Copy link

snikch commented Aug 27, 2013

Just thought I'd drop my 2c in here.

For responses which you want to consider public as far as cache control goes, it can be necessary to add in the Access-Control-Allow-Origin header, despite the lack of the Origin request header. Having this configurable would be excellent. We have an issue where Rack::Cache is storing a response that doesn't have the Access-Control-Allow-Origin header, and is returning it for requests even if they have the Origin request header.

@snikch
Copy link

snikch commented Aug 27, 2013

For the record, we solved the issue by adding a Vary: Origin header to all requests that could possibly be CORS.

@lsimoneau
Copy link

We couldn't use the workaround suggested by @snikch as adding Vary: Origin prevents our CDN from caching any requests, so we ended up writing another middleware to inject a fake Origin header into all requests before they hit rack-cors:

class InjectOriginHeaderMiddleware
  def initialize(app)
    @app = app
  end

  def call(env)
    # Force rack-cors to always return Access-Control-Allow-Origin
    # by always setting the "Origin:" header in the request
    env['HTTP_ORIGIN'] ||= 'force-CORS'
    @app.call(env)
  end
end

In application.rb:

config.middleware.insert_before Rack::Cors, "InjectOriginHeaderMiddleware"

@Taytay
Copy link

Taytay commented Jul 4, 2018

This issue is 3 years old, but this strict interpretation is indeed causing us issues as described by folks above. In particular, we would like to cache a VERY specific set of headers as our response for our javascript files, regardless of whether the origin is set. By varying the responses based on the request, it is possible for us to have the wrong responses get set in our CDN's cache, which causes subsequent valid requests to fail.

We might have to manually add these headers as suggested, but I welcome other suggestions or options to force this header.

On a related note, imagine that we have a very particular domain (example.com) that we'd like to specify as a valid origin. So, we'd like to always respond with the header:
Access-Control-Allow-Origin: http://example.com, regardless of which origin was used in the request.
At present, even if we do specify a origin, if we specify an origin other than example.com, the CORS headers are not returned. I realize that this is to spec, but is there a way to force these headers to show up, even if the origin is incorrect?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants