0

Lets say I have a site at myapp.com that talks to the api at myapi.com. For that to work I have to turn on CORS. I want to do it like that:

Access-Control-Allow-Origin: *

and my API authentication is performed via a custom Authorize header (with e.g. Bearer token).

As far as I can see it is safe to do since an attacker website would have a way of obtaining this token or sending it automatically.

Is this correct?

P.S. I want to have a "*" to e.g. not have problems with localhost development or some other environments where myapp.com runs, e.g. stage-myapp.com, etc.

Ilya Chernomordik
  • 2,287
  • 1
  • 26
  • 38
  • so basically you do not need the Access-Control-Allow-Origin: * but because you are unable to setup a proper Development environment you want to lower the protection offered by this header. I would suggest trying to solve the actuall problem (getting a proper dev environment) instead of abbusing a header for this. – LvB Sep 21 '20 at 11:06
  • Well, it's actually more of a theoretical question at this point, I just want to understand if this has any additional risks or not. I would assume e.g. Facebook og Google api does allow to be called from anywhere while providing security at the same time? – Ilya Chernomordik Sep 21 '20 at 11:24
  • if you want browsers to be able to consume your API off-site, then yes. – dandavis Sep 21 '20 at 19:03
  • To anyone reading this question and the accepted answer: please bear in mind, for your sake and that of yours users, that CORS is not a defence for anything. Rather, CORS is meant to relax the Same-Origin Policy. All things being equal, activating CORS always make you less (not more) secure. Even something as innocent as Access-Control-Allow-Origin: * can, in some contexts, be insecure. – jub0bs Mar 16 '23 at 21:09

1 Answers1

0

Theoretically, the Access-Control-Allow-Origin: * is just another defense in depth solution.

it's an easy way to make your endpoint have 1 more layer of security, especially from malicious websites tricking browsers.

it is by no means a sole solution to protect an api endpoint with (custom clients can just ignore the header. and attackers will just work around it if they can)

So, if your API has proper other safeguards and monitoring you can set this header to the * value. (older browsers still ignore this header anyway).

Google and Facebook however have a dedicated team protecting there infrastructure from abuse, so they are bad examples to use for your consideration.

in the end its all down to your threat model... does it allow for this type of use r not. (e.a. is your system prepared for the potential abuse of your API or do you really need the additional protection that this header offers.

A possible workaround is making your API smart enough to return a custom header depending on where the request came from and limit that list to a whitelist of allowed domains.

LvB
  • 8,943
  • 1
  • 30
  • 47
  • Thanks for the answer, I am just wondering what benefit do I get by limiting to a specific domain compared to a wildcard? – Ilya Chernomordik Sep 21 '20 at 11:58
  • The * is handled specially:

    For requests without credentials, the literal value "*" can be specified, as a wildcard; the value tells browsers to allow requesting code from any origin to access the resource. Attempting to use the wildcard with credentials will result in an error.

    • See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin
    – LvB Sep 21 '20 at 12:00
  • will allow a site running at any domain to call my API, but since it's protected by the header with a token, the only thing they can achieve is some DDOS attack which could anyway be done directly from any other client than browser. I am just trying to see which benefits do I get with setting the response header to my domain only instead of *?
  • – Ilya Chernomordik Sep 21 '20 at 12:17
  • Authentication credentials are not allowed with the * domains... So if your API request authentication headers, you can not use * – LvB Sep 21 '20 at 12:19
  • I see, do you know how is the problem solved for a "public" API that should have authentication? (e.g. google or facebook, etc.)? Do they accept token in some other way or they do as you say: return origin in the CORS header? – Ilya Chernomordik Sep 21 '20 at 12:32
  • Read the documentation I linked earlier. But basically you return a limited source on the request. – LvB Sep 21 '20 at 16:56
  • I see now, thanks a lot for the explanations! – Ilya Chernomordik Sep 22 '20 at 07:39
  • the Access-Control-Allow-Origin: * is just another defense in depth solution. No, quite the contrary, since CORS consists in relaxing security. – jub0bs Mar 09 '23 at 17:59
  • @jub0bs we are talking an API, not a website... the Access-Control-Allow-Origin is a browser specific feature... so as a result its just another defense in depth.

    CORS itself is just a defense in depth solution. (that doesnt mean its a bad defense or anything... it is just not something that should be used as is... but as part of a bigger plan.

    – LvB Mar 16 '23 at 11:00
  • @LvB The term "Allow" in the name of that header or the fact that the S in CORS stands for "Sharing" should give you a clue that CORS is no defence at all. This is a very common misconception, though: rather, CORS is meant to relax some of the Same-Origin Policy's restrictions; all things being equal, activating CORS always makes you less secure, not more secure. Since CORS is no defence mechanism, it cannot be a defence-in-depth mechanism. – jub0bs Mar 16 '23 at 11:19
  • @jub0bs the acces-control-allow-origin header manages on what origin (domain) a specific weakening of the CORS protection is allowed... your statement is there for wrong for this header, but correct when looking at CORS as a whole. – LvB Mar 16 '23 at 11:27
  • @LvB How is my statement wrong? If the server doesn't participate in the CORS protocol at all and omits the Access-Control-Allow-Origin header altogether from its responses, browsers won't allow any cross-origin clients to read the server's responses. Therefore, it's always safer to omit this header than to include it. Including it doesn't necessarily expose your users to viable attacks, but it does relax restrictions that are in place by default in virtue of browsers implementing the SOP. Your whole answer implies that CORS somehow strengthens security, which is incorrect. – jub0bs Mar 16 '23 at 12:26
  • @jub0bs you need to reread both the question and my reply. basically omitting the header is not safer. and you wronly assume the API will be consumed by a browser...

    having CORS set up correctly enhances security as part of a indepth defense. by specifically specifying how to handle request. not just CORS requests...

    – LvB Mar 16 '23 at 13:33
  • @LvB Access-Control-Allow-Origin is a CORS-response header. It has no purpose outside of the CORS protocol. Besides, it has no effect on user agents that don't implement the SOP; therefore, to a backend (rather than frontend) client that consumes the API in question, that header is useless. Perhaps you should read about the SOP and CORS some more... For concrete cases in which including Access-Control-Allow-Origin: * introduces vulnerabilities, see https://security.stackexchange.com/questions/227779/concrete-example-of-how-can-access-control-allow-origin-cause-security-risks/254684#254684 – jub0bs Mar 16 '23 at 13:46
  • "Note that CORS was never a defense" wrote Anne Van Kesteren, author of the Fetch standard (which contains the de facto CORS specification) in a 2018 tweet. – jub0bs Apr 16 '23 at 15:16