56

I recently learned about CORS and got the impression that its purpose is to prevent XSS. With CORS, the browser blocks requests to different domains, unless particular headers are in place.

But if a person with malicious intent injects some JavaScript into a page to steal users' cookies and send them to a URL he controls, all he has to do is add the following header on the server side to make the request work anyway:

Access-Control-Allow-Origin: *

So how does CORS prevent XSS? Or did I misunderstand the purpose of CORS, and it simply has nothing to do with XSS per se?

  • 3
    all he has to do is add the following header on the server side to make the request work anyway - if somebody has access to HTTP header config on the server there are bigger problems than cross-domain attacks. – user81147 Dec 23 '15 at 14:28
  • 10
    He can do that because it's his server (in the scenario I suggested): "a URL he controls". – Gigi Dec 23 '15 at 14:30
36

TL;DR: How does CORS prevent XSS? It does not. It is not meant to do so.

CORS is intended to allow resource hosts (any service that makes its data available via HTTP) to restrict which websites may access that data.

Example: You are hosting a website that shows traffic data and you are using AJAX requests on your website. If SOP and CORS were not there, any other website could show your traffic data by simply AJAXing to your endpoints; anyone could easily "steal" your data and thus your users and your money.

In some cases that sharing of data (Cross Origin Resource Sharing) is intended, e.g. when displaying likes and stuff from the Facebook API on your webpage. Simply removing SOP to accomplish that is a bad idea because of the reasons explained in the above paragraph. So CORS was introduced.

CORS is unrelated to XSS because any attacker who can place an evil piece of JavaScript into a website can also set up a server that sends correct CORS headers. CORS cannot prevent malicious JavaScript from sending session ids and permlogin cookies back to the attacker.

  • 1
    Whether or not SOP and CORS were there, any other website could proxy its users' requests. – Damian Yerrick Dec 23 '15 at 15:22
  • 3
    @tepples: But in this case the cookies for the original site will not be sent with the request and thus it would not be possible to read data which only the logged in user can see. – Steffen Ullrich Dec 23 '15 at 15:50
  • 8
    Exactly. CORS doesn't restrict or prevent anything. CORS is intended to provide a controlled way to relax the restrictions imposed by the same-origin policy. Without CORS, the web would still be just as secure (though not as functional). – Ajedi32 Dec 23 '15 at 16:42
  • 1
    Yes, they can unless the sensitive data is protected with a login. A foreign website has no access to the session cookies of the "target"/"cors-protected" website. Thus, a malicious server cannot send a valid request for the data - only the users browser and the resource owning party can construct a valid request – marstato Apr 13 '17 at 13:10
  • 3
    The example is misleading. This is not the purpose of CORS. Your rival can make a similar website to your, which on the backend would call your server with proper origin headers, and CORS won't stop it. – Georgii Oleinikov Jul 21 '17 at 8:54
16

Cross-Site-Scripting (XSS) is the execution of attacker defined script code in the context of another site. CORS does not prevent XSS, in fact it is unrelated to XSS.

Instead CORS offers a way to weaken existing restrictions on Ajax requests (i.e. XMLHTTPRequest) in a way which hopefully does not introduce more security problems. Traditionally XMLHTTPRequest was restricted to communicate within the same origin, that is it was not possible to sent a request to some external site. This restriction was done so that an attacker cannot do a cross site request and get the result of the request back, because this would allow an attacker to read data from sites where the users was logged in (because session and other cookies are sent with each request to a site).

With CORS this restriction is partly removed. It is now possible to sent an XMLHTTPRequest to another site but the result can only read inside the application if the remote site explicitly added some CORS headers which allow the access. But again, this is not executing script on the remote site and thus this is unrelated to XSS.

  • 4
    To be clear, even before CORS it was possible to send a request to an external site by using a form. What CORS allows is actually reading the response back from a cross-site AJAX request. – Ajedi32 Dec 23 '15 at 16:49
2

Other answers are correct that XSS and CORS are not directly related (although CORS can help limit impact of XSS to the vulnerable site).

Basically CORS allows your website js frontend code to access your website backend with the cookies and credentials entered in your browser while your backend stays protected from some other site's js, asking client browser to access it (with credentials user has obtained).

This is when Control-Allow-Credentials: true is set (which allows browser to send cookies and basic/gssapi/napi auth). I'm still not sure how CORS helps without this option. See my question "do I need to restrict origin in an API app?"

2

CORS does not protect anything, SOP (Same Origin Policy) protects something instead. SOP protects the target domain and the browser user.

In fact, CORS weaken existing restrictions of SOP to help website developers to use shared data from other origins.

0

CORS and XSS are related, but not directly. The best way to explain it is by example: we shall consider 3 servers (your_bank.com, api.your_bank.com, badguy.com*) and 1 client (your browser).

  1. You are logged into your_bank.com (your browser holds authentication cookies).
  2. Your_bank.com makes transactions by sending AJAX requests to api.your_bank.com using yet more cookies (held in the browser). Normally your browser's SOP would block this request, but instead CORS (granted by api.your_bank.com) allows it.
  3. You see something shiny at badguy.com, and visit that page.
  4. Badguy.com attempts transactions by sending AJAX requests to api.your_bank.com using the cookies for that domain held in your browser.

At step 4, your browser (which is not compromised) owns the "Origin" header sent to api.your_bank.com. If CORS is correctly configured, this step will be blocked. Your browser, being the owner of the cookies and request headers, is gatekeeping access to other sites.

* The badguy.com site may be legitimate, but suffer from an XSS issue.

  • "this step will be blocked" I agree that the read will be blocked (i.e. the malicious origin cannot retrieve sensitive information from your bank account), but writes currently aren't blocked by the browser (so CSRF may be in play here) – multithr3at3d Jan 14 at 22:21

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.