CORS Discusion
Last updated
Was this helpful?
Last updated
Was this helpful?
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 CSRF attack is successful or not.
The only time the SOP comes into play with CSRF is to prevent any token from being read by a different domain.
All CORS does is relax the SOP when it is active. It does not increase security, 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.shareimprove this answeredited Nov 22 '15 at 14:42answered Aug 27 '15 at 17:00SilverlightFox29.4k44 gold badges5353 silver badges148148 bronze badges
3This 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. – Alex Urcioli Mar 6 '16 at 20:30
1All 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 Mar 7 '18 at 7:32
@Daniel What kinds of requests are blocked by the SOP? – curiousguy Jun 25 '18 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? – tonix May 4 at 16:09
@ton Yes, you are correct for all (?) modern browsers. See my post here: markitzeroday.com/x-requested-with/cors/2017/06/29/… It has some examples, and shows mitigation by checking for a custom header. – SilverlightFox May 4 at 21:59
I know this answer is a few years old now, but there are browser extensions which can spoof the origin header. I've never tested it but one would think it's possible an attacker can leverage the victim's browser's extension. Maybe the user left the Origin header set and forgot to remove the value or disengage the extension. Or, the attacker might be able to directly enter a value to the extension. I'm just thinking out loud here. – user3621633 May 31 at 15:03
Let us start by defining the term "origin". The origin of a page is decided by three unique factors: hostname, protocol and port number. For example, http://test.com
and https://test.com
have different origins as the protocol is different. Similarly http://one.test.com
and http://two.test.com
have different origins as the hostnames are different. The origin property is also different for two services running on the same host with different port numbers e.g. http://test.com:8081
and http://test.com:8082
are considered to be different origins.
Same Origin Policy (SOP) is a browser-level security control which dictates how a document or script served by one origin can interact with a resource from some other origin. Basically, it prevents scripts running under one origin to read data from another origin.
Cross-domain requests and form submissions are still permitted but reading data from another origin is not permitted. This means that if you are performing a CSRF attack on a vulnerable site which results in some server side state change (e.g. user creation, document deletion etc), the attack will be successful but you would not be able to read the response.
In short SOP only prevents reading data which was served from a different origin. It does not cover cross-domain form submissions which are used to carry out a CSRF attack.
As far as performing cross-domain communication using AJAX is concerned, there are a few other security controls which dictate the communication. Refer to Cross Origin Resource Sharing. CORS allows different origins to communicate and share data in a controlled way and a CORS misconfiguration may also result in security vulnerabilities.
Note that SOP does not prevent resources hosted on different domains to be embedded in a page by using script tags, CSS and image tags. While this might not allow a direct reading of the contents, side effects of the loading and rendering can be used to determine (parts of) the content. Note also that Websockets are not covered by SOP at all and thus cross-site reading is possible.
How are they exception, SOP only prevent script running under one origin to read data from other origin, if you use img tag and src set to different origin, you won't be able to read image data, though it is rendered to user. So why are you calling it exception it is usual behaviour. – Suraj Jain May 3 '18 at 18:30
You have made a contradictory statement, How is the image getting rendered if the script sitting in the requesting domain is not able to read it? – Shurmajee May 4 '18 at 6:09
1Image gets rendered and displayed to user, but javascript in script tag won't be able to access it. – Suraj JainMay 4 '18 at 6:27
2Actually exception would be gravely incorrect term, what is definion of SOP '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.', now the other answer mentions images and script tag because often people get confused with these in relation to SOP, I think you should remove exception it is not phrased correctly, and would at best confuse the reader. The definition of SOP as I have given above, explains all clearly. – Suraj Jain May 4 '18 at 9:27
1Embedding of resources in not an exception to start with, SOP was never meant to block them so they are not exception. – Suraj Jain May 4 '18 at 9:27
Same Origin Policy (SOP) preserves the data of other domains...
There are two parts to the SOP:
It prevents scripts on origin A from reading data from origin B.
It prevents sites on origin A from sending anything but so called "simple" requests to origin B. Simple requests are limited to GET and POST, and only a few headers can be modified.
...and therefore nulls out the use of CSRF.
The SOP does not protect against CSRF. Why?
A CSRF attack is done by sending a request, and not by reading anything from the response. In fact, you neither can nor need to read the response.
You would normally use simple requests in a CSRF attack.
As you can see, the limitations mentioned above that the SOP puts in place does not prevent CSRF attacks.
Now considering the Same Origin Policy only applies to XMLHTTPRequest...
No, it does not. It applies to all data a browser handles. If you use XMLHTTPRequest, an ordinary form, or the fetch API is irrelevant. The same restrictions apply.
...so with a cleverly crafted form, I can do a POST request witch voids the SOP and hence the need for CSRF tokens.
With a clever crafted form you can make a POST request that executes a CSRF attack, yes. And that is why you need special protection, such as CSRF tokens.
Now with all of this, does the CSRF kind of work around the SOP or works through it?
A site A can cause a request to the different site B in various ways, for example with including an image from site B inside the HTML from site A (i.e. <img src=http://B/...
>) or do similar things with forms or Javascript or HTTP redirects. Requests which are initiated from one site but are directed to another site are called cross-site requests.
Cross-Site Request Forgery (CSRF) means that a cross-site request can be misused. This is typically the case because an existing session cookie from a previous connection to site B is sent to each request on this site, even if the request is initiated from site A, i.e. cross-site. This means that the request is executed with the identity of the user logged into side B. A successful CSRF attack means that such a cross-site request can cause harm, for example by changing the DNS settings in a router vulnerable to CSRF.
Same-Origin Policy (SOP) does not make CSRF impossible but it somehow limits the impact of CSRF in that the request gets send to site B but the result returned by the server of site B can not be seen by the attacker. Thus SOP makes CSRF write-only, i.e. CSRF can be used to execute unwanted actions but it cannot be used by itself to exfiltrate data from site B. For example an external attacker might use a CSRF vulnerability in a internal company Wiki to create a new posting in the name of an existing user or delete a posting, but due to SOP he cannot read the content of the internal Wiki and send it back to the external attacker.
Note that not all cross-site communication is restricted by the SOP. Notably Websockets are not restricted and thus it is for possible for an attacker at site A to use a browser as a trampolin to fully communicate with a Websocket at site B with the permissions of the logged in user, i.e. both write and read data
P.S. Taken from my blog.shareimprove this answeredited Jul 23 at 15:20horcrux13266 bronze badgesanswered Apr 10 '17 at 6:08Shurmajee5,79644 gold badges2121 silver badges5656 bronze badges
I'm not sure what "working around" or "working through" the SOP would mean. Instead, let me say this: CSRF is possible because browsers lets you send cross origin POST requests. shareimprove this answeranswered May 9 '18 at 10:39Anders51.6k2222 gold badges147147 silver badges173173 bronze badgesadd a comment2