5

I have a misunderstanding regarding CORS' Access-Control-Allow-Origin header.

It's name says "allow" from which I understand that if I make a request from an "Origin" that is not allowed the request should fail.

But I can always change /etc/hosts to have the "Origin" point to my IP address.

For example, for a response that might contain this:

Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: http://example.com
Access-Control-Expose-Headers: Access-Control-Allow-Origin,Access-Control-Allow-Credentials

I can always modify /etc/hosts and have:

127.0.0.1   example.com

... and the call will work.

What exactly is this header allowing? Can I use Access-Control-Allow-Origin: * instead of Access-Control-Allow-Origin: http://example.com? What's the difference?

3

It's name says "allow" from which I understand that if I make a request from an "Origin" that is not allowed the request should fail.

That is right (depending on the request). But disallowing a request is not a property of CORS, it's because of the same origin policy.

CORS isn't really a header meant to secure anything, it's a header meant to weaken the same origin policy and to allow cross origin requests (which may be required by some applications).

It is especially not designed for access control, so you being able to access websites via changing your systems configuration does not affect its security in any way.

2
  • I see... but then how is Access-Control-Allow-Origin: http://example.com different from Access-Control-Allow-Origin: *? Can I use * for everything?
    – pepe
    Apr 14 '16 at 15:31
  • 1
    @pepe It depends on the situation, but you probably shouldn't. If you use *, it basically means that the same origin policy doesn't exist anymore. So any other website can perform requests to your site from a clients browser and read out data, etc. For example, this means that any CSRF protection is useless. And obviously it may leak sensitive data.
    – tim
    Apr 14 '16 at 15:41
3

CORS policy limits what code loaded from site A and executed on your browser can do with site B, i.e. limits what cross-origin requests can do. It is not to restrict what can be done with site B in general, i.e. it cares only cross-origin requests and does not provide any kind of authentication control.

You are right that you could in theory just modify your system to bypass this policy. But the attacker on some remote web server can not do it. If the attacker on site B wants to use a cross-site request against site A but site A allows only site G then the attacker would somehow need to appear as site G for your browser. In order to do that the attacker must have access to your system or to the DNS settings of site G, which is not something one could usually expect from the attacker.

0

Access-Control-Allow-Origin changes the protection offered to the end user in regards to how the Same Origin Policy handles AJAX responses.

If a user is willing to mess around with host files in order to change this protection even further on their own, then the only thing they are compromising is their own security.

The header allows another origin to read an AJAX response if a cross-origin request is sent to the origin that outputs the header.

Can I use Access-Control-Allow-Origin: * instead of Access-Control-Allow-Origin: http://example.com? What's the difference?

The difference is the first option allows any origin to read AJAX responses. The second option only allows http://example.com to read AJAX responses.

If Access-Control-Allow-Credentials is true, then the first option won't work - CORS will not let you open your website up to global credentialled requests. If it did, and your website held confidential information (for example Gmail may have an AJAX function that returns the messages in the inbox), then any website a user visits would be able to read this confidential information from your website in the context of the current user's session.

If you do actually desire all origins to be able to read from the current user's session, then you can read the Origin request header and then reflect this origin in the Access-Control-Allow-Origin header (taking care to properly sanitise of course, removing CRLFs and the like). This would effectively be the same as outputting Access-Control-Allow-Origin: * and allowing credentialed requests via Access-Control-Allow-Credentials.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.