4

I have an app serving a rest-like API and an angular UI for it. Clients can use API directly or use the UI (if client is a human).

The app should return special headers as well handle OPTIONS requests properly for CORS to work with the browser and the xhr requests performed by angular to be allowed.

My question is why? What is this protecting the user from? Another question is whether there is any security issue in allowing wildcard * all domains to access the API? I don't care if user uses curl, or has his/her own script or has built custom UI for this API. Why should I put restrictions?

The only possible reason I can see for this is to avoid possibility of a third-party site to use credentials stored in browser to access the API. But this should be impossible unless Access-Control-Allow-Credentials: true header is set. But this can't work with a wildcard allow-origin header.

Clarification: the question is not why restrict access but why restrict origin domains when Access-Control-Allow-Credentials header is false. I'm sorry if my wording was not clear about this.

4

4 Answers 4

1

Found a blog. From it wildcard does not sound dangerous unless site is using client network as a kind of a security measure.

I can imagine somebody trying to reach into a VPN for example through victim's browser. Would require a lot of internal knowledge but if attacker is an ex-employee for example, he/she may have such knowledge also can use internal contacts and trick them into opening a rogue web page to execute the attack.

2
  • 1
    Just extending the answer.. Imagine you're reading a blog on "mysite.com" and a script on that side could access your google/yahoo/any_other services while you're logged in. So the idea is to prevent unwanted cross-site scripting.
    – gusto2
    Commented May 16, 2017 at 7:22
  • @gusto2, not sure what you are extending but you comment doesn't say how can that happen when Control-Allow-Credentials is false. I'd say it is plain wrong in fact. Commented Dec 15, 2017 at 20:15
1

It sounds like you have a little bit of confusion about how CORS works and when it is applicable, in particular because of this from your question:

Another question is whether there is any security issue in allowing wildcard * all domains to access the API? I don't care if user uses curl, or has his/her own script or has built custom UI for this API. Why should I put restrictions?

The thing you have to keep in mind is that CORS and the pre-flight OPTION requests only matter for browsers. If someone is building their own API and using CURL or other server-to-server requests, there will never be a pre-flight request and any Access-Control-Allow-Origin headers will be completely ignored.

If, however, you attempt to make an ajax request from a browser via javascript, then the browser itself will enforce CORS: it will send off a pre-flight OPTION request (if required) and throw away the response if everything doesn't check out.

Also keep in mind though that CORS protects against reads, not writes. If you make a POST request via javascript/ajax the request will still get sent to the server: the calling javascript application will simply not get to read back the response if the CORS check doesn't validate.

Your own answer is getting at the reason why you probably want to use CORS (although there are definitely times when you might want to allow all origins). Remember that all browser requests also come with cookies attached. As a result, if your application is authenticated via cookies, and if any origin is allowed, then theoretically anyone can put javascript on any site that makes API calls on behalf of authenticated users.

As an example, imagine that Amazon has an API call that is made via javascript when you click the "One click purchase" button on a product landing page (for reference, such an API call certainly exists). Imagine further that authentication credentials are managed via cookies (possibly true), and that an attacker spent some time figuring out the structure of the API call (which is not impossible since the Javascript code is always available for inspection).

Enter you (the attacker). You are selling a bag of dirt on amazon for $200. No one is buying your product. So you write some javascript that calls the amazon endpoint to execute the one-click-purchase on your bag of dirt. You don't want to buy it yourself though, so instead you make a website with cat videos that becomes very popular (after all, who doesn't like cats?). On that website you put your javascript that calls the one-click-bag-of-dirt-purchase automatically on page load. Now, every time someone visits your website while also being logged in on amazon, they immediately purchase your bag of dirt without taking any action. Your orders start rolling in and amazon has a big mess on their hands because of their lack of good security.

That may not be the best example of why having an open origin can bite you, but hopefully it gets the point across. Again, there are certainly some API calls for which an open origin is perfectly reasonable. A good example is most social media apps: twitter/facebook/etc specifically provide javascript that is meant to be executed on other websites so that you can easily pull down a recent twitter feed. In return, they have their own hoops you have to jump through in order to authenticate your API calls. So there are definitely reasons why you do want to open up your API. However, there are also reasons why you don't. In either case, this only matters for in-browser API calls. Curl and other "direct" HTTP requests ignore CORS all-together.

3
  • I said that I don't care how service is accessed. I didn't ask about curl if you read my sentence. Moreover there are some other things you don't account to. POSTs are not pre-flighted only for a few types (see stackoverflow.com/a/39736697/520567). Also when allow wildcard is * then Access-Control-Allow-Credentials: is not allowed, thus the attack you describe should be impossible. My observation is that to allow custom UIs, browsers should let user override CORS restrictions manually but I guess they wanted to prevent the situation with certificate trust overrides. Commented Aug 17, 2017 at 17:44
  • 1
    @akostadinov I think that what we have here is a failure to communicate. It wasn't clear to me in your original question that you were asking, effectively, "why can't I just turn off CORS?". That is easy to answer: there certainly are plenty of vulnerabilities that could happen with CORS simply off. The example I gave is a perfect example of a potential vulnerability. It is not possible because of CORS restrictions, but if someone could just turn off CORS on a per-site basis then these kinds of security holes would open up unexpectedly, and it is the browser's end-users that would suffer. Commented Aug 17, 2017 at 18:49
  • It seems like you are asking "why can't I turn off CORS?". Browser's have a duty to protect the security of their end-users: not make your life easier. If people could turn off CORS for their sites, then there are plenty of web developers out there that would turn it off without understanding the security implications, and all of a sudden any private information stored on those servers would potentially become easy targets for hackers. I would much rather have the browsers enforce basic security then allow someone else to play fast and loose with my personal information. Commented Aug 17, 2017 at 18:53
1

What is the Same-Origin-Policy?

From Mozilla:

The same-origin policy restricts how a document or script loaded from one origin can interact with a resource from another origin. It is a critical security mechanism for isolating potentially malicious documents.

All modern browsers enforce this.

Why do we have it?

This prevents an attacker from tricking a user into loading a malicious URL into the client and doing something like transferring money to the attacker because a browser just executes the code it sees.

Check out the OWASP Info on CSRF. Specifically, under examples and "How does the attack work?"

What is Cross-Origin Resource Sharing?

From Mozilla:

Cross-Origin Resource Sharing (CORS) is a mechanism that uses additional HTTP headers to let a user agent gain permission to access selected resources from a server on a different origin (domain) than the site currently in use.

To summarize, a SECURITY BYPASS MECHANISM.

Why do people need CORS?

Because people still think AJAX is cool. Joke. Alternatively, you could say, developers still use a client side asynchronous model to load data into their applications.

EDIT Added based on comment

Why restrict this origin domain if Access-Control-Allow-Credentials header is set to false (or missing)?

You probably know this but Access-Control-Allow-Credentials only controls whether the client/server accepts credentials being exposed to the site.

Based on your responses, your API doesn't require credentials thus this flag is irrelevant -- but should you use CORS with a wildcard '*' or returning the origin or should you restrict the origin?

There is probably a lot of red text on the internet, but if your API is open/public than using the wild or echoing the origin is fine.

If your API is more organization specific, its better to whitelist the domains that would use it, check against that list, and return the origin in the whitelist. These are just good security practices.

I wouldn't disable it though

1
  • Tried to clarify my question. I think my wording was not clear. Basically question is why restrict origin domain when Control-Allow-Credentials header is false (or missing). Commented Feb 14, 2018 at 16:01
0

I am also confused about this, my understanding is like this.

For an origin in the Access-Control-Allow-Origin, it can read sensitive information from the server on behalf of authorized users. But for others, the browser will block them.

And more than that. When the browser sends cookies and the server returns sensitive information related to the user based on the cookies, if the server is not explicitly allowed to do so by setting Access-Control-Allow-Credentials: true, the browser will prevent the script from reading the response.

But if you set Access-Control-Allow-Origin: * and Access-Control-Allow-Credentials: true, it means any origin can make requests on behalf of authorized users. This will increase the risk of information leakage, so the specification does not allow it.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .