66

I've been reading in the last couple of days about CORS and in a lot of places it's mentioned as it is a "Security" feature to help the world from cross domain forgery.

I still don't see the benefit and the reasoning for CORS. Ok, browsers will do a preflight request / server will validate the origin. But an attacker can easily create an HttpRequest top-bottom with whatever Headers(Origin) he wants and he will get access to the resource.

How is CORS helping and what's the benefit of it?

0

6 Answers 6

83

I'll start my answer by saying that many people misunderstand the Same Origin Policy and what CORS brings to the table.

Some of the up-voted answers already here are stating that the Same Origin Policy prevents cross-site requests, and therefore prevents CSRF. This is not the case. All the SOP does is prevent the response from being read by another domain (aka origin). This is irrelevant to whether a "classic" CSRF attack is successful or not.

By "classic" I'm referring to the types of request that were possible before CORS came about. That is, the types of request that can be sent via HTML forms as well as XHR (e.g. GET or POST without custom headers).

The only time the SOP comes into play with "classic" CSRF is to prevent any token from being read by a different domain.

Of course, now we have CORS and all sorts of cross-domain requests are possible such as PUT and DELETE, CORS does in fact protect against these by requiring a pre-flight. However, generally speaking CORS is not providing greater net benefit because the reason this functionality is available in the first place is due to CORS.

All CORS does is relax the SOP when it is active. It does not increase security (except perhaps allowing cross-domain resource sharing to be standardised and prevent developers from introducing flaws with something like JSONP), it simply allows some exceptions to take place. Some browsers with partial CORS support allow cross site XHR requests (e.g. IE 10 and earlier), however they do not allow custom headers to be appended. In CORS supported browsers the Origin header cannot be set, preventing an attacker from spoofing this.

I mentioned domains were different origins. Origins can also differ by port and protocol when talking about AJAX requests (not so much with cookies).

Finally, all of the above has nothing to do with forged requests coming directly from an attacker, for example with curl. Remember, the attacker needs to use the victim's browser for their attack. They need the browser to automatically send its cookies. This cannot be achieved by a direct curl request as this would only be authenticating the attacker in this type of attack scenario (the category known as "client-side attacks").

The benefit of CORS is that it allows your domain to allow reads from another trusted domain. So if you have http://data.example.org you can set response headers to allow http://site.example.com to make AJAX requests and retrieve data from your API.

14
  • 6
    This is the most correct answer. Also nobody seems to be mentioning that most modern CORS libraries let you whitelist what Origins you want to allow. Everything I read seems to assume you should just be allowing all Origins which usually is not the case for most people. Mar 6, 2016 at 20:30
  • 1
    All the SOP does is NOT prevent the response from being read by another domain! It doesn't even allow browsers to send a preflighted request to another domain.
    – Daniel B
    Mar 7, 2018 at 7:32
  • @Daniel What kinds of requests are blocked by the SOP?
    – curiousguy
    Jun 25, 2018 at 7:58
  • I have some thoughts regarding POST requests without custom headers and with a standard Content-Type header value (e.g. application/x-www-form-urlencoded). For this requests, the browser (at least, Chrome) following the CORS policy WILL NOT make a preflight OPTIONS request and will send the POST request right away. This means that if a user visits the site of an attacker and this malicious site makes this POST request via AJAX with the withCredentials options set to true (thus, sending session cookies), then CSRF would be successful. Am I right? May 4, 2019 at 16:09
  • 1
    @jub0bs: True, I used "cookies" as the most common example, but it could be a different form of auth such as digest, basic, certificate based, or, as you mention by request IP address only. I answered a similar question along those lines here in regards to CORS . Sep 1, 2021 at 11:33
16

You're mixing things up. CORS is not meant to protect your application from crafted http requests, it's meant to protect you from a certain kind of attacks that "steals" the user's cookies or access tokens, by checking what sites can access your resource.

It's mostly used to protect your server/application from cross-site request forgery, where a malicious site will do a request on behalf of the user, possibly with malicious intents (credentials change, money transfer...), exploiting the fact that the browser will send any login and session cookie still alive and valid for your site.

If CORS is correctly configured, the ajax request of the attacker's site will be rejected, as, by default, it will only accept requests by the same site.

This DOES NOT mean you should not sanitize your inputs, and only protects you from a certain type of CSFR attacks. Should the attacker get your user's cookies/access tokens he will be granted access anyway, and that's why most authentication processes should use SSL as an additional layer of protection.

PS: This assumes the browser your user is using is up to date, has no flaws and is correctly obeying the same origin policy.

EDIT: As for preflight requests, this is an additional measure to be sure the site is granted access, and are not done for all cross-origin requests

4
  • This answer really cleared things up for me. Now I understand that it is the requested third-party resource that needs to allow the request, not the server that generated the requesting page.
    – alexw
    Dec 14, 2015 at 1:39
  • 9
    @Sebastiano, CORS is not meant to protect you from CSRF. (CSRF would stil be possible via <img src= and <form action= regardless of CORS.) CORS is meant to protect you from the site you are currently visiting, preventing them from accessing and reading the response of other sites (Gmail / banking sites) that has your sensitive details.
    – Pacerier
    Jan 23, 2016 at 18:55
  • 1
    CORS is not for protection, but a resource sharing. To some extent it is just the opposite of CRSF. The former allows for cross-origin requests, the latter forbids (or prevent some malicious) cross-origin requests. Also CORS request is generally not rejected by the server, but the response from the server "rejected" by the client, i.e. the browser. So SOP does not necessarily prevent CRSF, as clarified in @SilverlightFox's answer.
    – wlnirvana
    Feb 20, 2020 at 7:57
  • 2
    @alexw please don't get confused by this answer. It's not correct. CORS makes your application LESS secure. Any of the security benefits this answer talks about, are actually already there by default because of the Same-Origin Policy. See my blog for a good explanation: levelup.gitconnected.com/… Dec 13, 2020 at 4:50
3

I've been reading in the last couple of days about CORS and in a lot of places it's mentioned as it is a "Security" feature to help the world from cross domain forgery.

You either misunderstood the benifits of CORS or may be you have read that in some amateur blogs done by developers who are more worried about how to make it work than how to make it safe (if you understand what I mean), because CORS rather makes your web application vulnerable to such attacks (CSRF) when you open cross-origin requests from the attacker's origin by using CORS with the following header: Access-Control-Allow-Origin: *

How is CORS helping and what's the benefit of it?

CORS was born to lighten the restrictions of the SOP for trusted requests only. But the problems start exactly with that trust. An attacker could do harm through the origins by forging malicious requests through GET and POST methods for example, and may expose you even DNS rebinding

5
  • 4
    What is the relevance of DNS rebinding in the context of CORS? If a DNS rebinding attack is successfully being carried out, then information is already being leaked (regardless of CORS headers). If CORS is incorrectly set up, then information can already be accessed without DNS rebinding. In either case, I don't understand why DNS rebinding deserved to be mentioned in your answer. Did I overlook anything?
    – Rob W
    Aug 26, 2015 at 16:02
  • @RobW If you implement CORS as it is, I mean without making the necessary to check the origin and host headers have the same host name then you are vulnerable to DNS rebinding.
    – user45139
    Aug 26, 2015 at 17:14
  • 2
    If you always reply with Access-Control-Allow-Origin: *, then the resource is already public, so DNS rebinding doesn't add any value. Could you give an example (requests & responses) where DNS rebinding and CORS together result in a security issue, which really requires both components in the attack?
    – Rob W
    Aug 26, 2015 at 17:18
  • @RobW what a resource author check when implementing CORS? By instinct he is likely (and we speak about developers) the origin header only. The origin headers displays from where the cross-origin request comes from, a developer forgets to check the host header, there comes the problem. If you want a proof of concept you may ask that in a different post (in order not to lead my answer off-topic: i mentioned that as an additional information to the OP, he asked only about CSRF)
    – user45139
    Aug 26, 2015 at 17:26
  • 6
    By the way your answer is phrased, DNS rebinding sounds like a serious vulnerability that is highly relevant to CORS, and somehow relevant to CSRF. In order to carry out an attack that abuses origin whitelists, the attacker has to control one of those origins. DNS rebinding is not going to help over there. If the attacker controls the origin, then the only thing where DNS rebinding could be used is to steal cookies that were set after a CORS-enabled request with credentials via an attacker-controlled host name. That attack sounds a bit far-fetched. Did you have anything else in mind?
    – Rob W
    Aug 26, 2015 at 18:01
3

Does it make sense to summarise all this as follows:

  • SOP (Single Origin Policy) ensures CSRF attacks can't be made from within a modern, up to date, browser due to the fact that the attacker would have to be POSTing from another domain.

  • CSRF (Cross-Site Request Forgery) tokens ensure that dangerous POST requests can't be made outside of the browser (where SOP doesn't apply, e.g. using curl), because they have no access to authentication data in user cookies outside of a shared browser experience.

  • CORS (Cross-Origin Resource Sharing) can be used to relax restrictions on SOP to browsers, but only if the resource server allows it through CORS headers. Therefore it has the potential to actually weaken security if used incorrectly.

2
  • 1
    Your first point is not accurate. CSRF attacks can be made because for simple GET/POST requests, all SOP does is stop the browser being able to read the response, the request still gets sent. The rest sounds ok. Dec 13, 2020 at 4:54
  • Second point also seems not accurate. CSRF attacks happen within the browser, because the browser will automatically send the session cookie to the trusted site. Requiring an additional CSRF token ensures the request cannot be forged. When using curl, you need to provide the session cookie yourself (that you don't have), so an attacker cannot make a successful request regardless.
    – henk
    Jan 14, 2022 at 10:29
2

As for this part,

browsers will do a preflight request / server will validate the origin. But an attacker can easily create an HttpRequest top-bottom with whatever Headers(Origin) he wants and he will get access to the resource.

From https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS

Additionally, for HTTP request methods that can cause side-effects on user data (in particular, for HTTP methods other than GET, or for POST usage with certain MIME types), the specification mandates that browsers "preflight" the request, soliciting supported methods from the server with an HTTP OPTIONS request method, and then, upon "approval" from the server, sending the actual request with the actual HTTP request method. Servers can also notify clients whether "credentials" (including Cookies and HTTP Authentication data) should be sent with requests.

As much as i am aware, if you use HTTP methods like 'PUT' instead of 'POST' and because making a cross-domain request using 'PUT' as the specified method will always be preceded by a pre-flight request checking to see if the Origin is allowed, this can prevent attacks in certain situations. This is because the origin can't be spoofed by the attacker as modern browsers don't allow client side scripting languages such as Javascript to set the 'Origin' or any custom headers cross-domain, the attack will fail.

Hope that helped.

3
  • It seems CORS helps protect against CSRF only comparing services with misconfigured CORS to services with properly configured CORS. As for services that do not interpret the Origin request header, do not respond to OPTIONS and do not include CORS headers, both old and modern browsers will stop malicious scripts from sending PUT requests against such: w3c.github.io/webappsec-cors-for-developers/#cors
    – eel ghEEz
    Jul 12, 2017 at 15:38
  • 2
    "non-standard HTTP methods like 'PUT'" what? PUT is certainly standard. Sep 20, 2018 at 18:24
  • @EvanCarroll replace "non-standard" with "not simple". PUT cannot be sent via the user's interaction with a browser. Only GET requests (user clicks on a hyperlink, or types something into the URL textbox), and POST requests (user clicks the submit button on a form). PUT/DELETE can only be sent via Javascript, which can execute in the background without the user/victim knowing about it. For more info, read "Why is PUT/DELETE treated differently to GET/POST?" section in medium.com/swlh/simulating-a-csrf-attack-part-2-bf6f378da625 Dec 13, 2020 at 5:02
1

Yes, it is helping, but not really by design.

CORS stands for Cross-Origin Resource-Sharing. It's not really intended for security. CORS is folded into the fetch API, so it's only useful for Javascript (more on that later). By default, fetch() can't grab what's not in the same origin because of the Single Origin Policy (SOP). CORS loosens that up by saying what other origins are allowed to access a resource. Also, XMLHttpRequest behaves the same way.

So, yes it can help block cross-site scripting (XSS) because the resource is trying to be accessed from across another origin. And technically, your server isn't blocking the request. It's browser that doesn't let the request go through by respecting the Access-Control-Allow-Origin header.

But that's only for Javascript. Browsers don't use CORS for Simple Requests.

That means simple GET requests (like fake images) don't get stopped by CORS. Also, POST requests not done in Javascript (ie: forms) don't trigger CORS. You still need protection against that. Security is only as strong as your weakest link, and once your start preventing CSRF at a server-level from Simple Requests, you'll realize that your CORS is just an extra layer that isn't truly necessary, but still nice to have.

1
  • 1
    "Yes, it is helping". No, it's not. For something to "help", it needs to provide more value than what is already available. By default, the Same-Origin Policy is used, and CORS adds no extra security to what is already there, at all. In fact, it makes things less secure by giving you the ability to allow other domains to make requests to your domain. "So, yes it can help block cross-site scripting (XSS)", again, no it can't, because by default, browsers do this anyway because of SOP. "Browsers don't use CORS for Simple Requests", replace 'CORS' with 'pre-flight requests'. Dec 13, 2020 at 5:06

You must log in to answer this question.

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