120

From my perspective, the technologies referred to as Cross-Origin Resource Sharing (CORS) and Content Security Policies (CSPs) seem to be very similar in purpose and implementation.

Both seem to allow you to whitelist the origins of resources which an uncompromised version of your webpage incorporates, via HTTP response headers. The only difference I can see is that CSPs seem to be more fine-grained in what you can approve in your HTTP response.

General Grievance
  • 4,555
  • 31
  • 31
  • 45
nickform
  • 1,573
  • 2
  • 12
  • 18

5 Answers5

135

CORS allows the Same Origin Policy to be relaxed for a domain.

e.g. normally if the user logs into both example.com and example.org, the Same Origin Policy prevents example.com from making an AJAX request to example.org/current_user/full_user_details and gaining access to the response.

This is the default policy of the web and prevents the user's data from being leaked when logged into multiple sites at the same time.

Now with CORS, example.org could set a policy to say it will allow the origin https://example.com to read responses made by AJAX. This would be done if both example.com and example.org are ran by the same company and data sharing between the origins is to be allowed in the user's browser. It only affects the client-side of things, not the server-side.

CSPs on the other hand set a policy of what content can run on the current site. For example, if JavaScript can be executed inline, or which domains .js files can be loaded from. This can be beneficial to act as another line of defence against XSS attacks, where the attacker will try and inject script into the HTML page. Normally output would be encoded, however say the developer had forgotten only on one output field. Because the policy is preventing in-line script from executing, the attack is thwarted.

mhadidg
  • 1,503
  • 17
  • 29
SilverlightFox
  • 32,436
  • 11
  • 76
  • 145
  • 9
    Much clearer and to the point than all mozilla/html5rocks/w3c documents together. Thx. – JepZ Dec 14 '16 at 22:47
  • That's not quite true - The Same Origin Policy will not prevent the AJAX request by default. It will only prevent the browser from accessing the result of the operation. Also, CORS can do more than just relax SOP. It can also further restrict - e.g. when "\*" is used as the "Access-Control-Allow-Origin" header, the browser will *not* send cookies and it will pre-flight certain requests. – Veita Oct 03 '22 at 17:18
  • @Veita That's what I meant by `and gaining access to the response`, the **and** is key here. I also clarify this further on: `it will allow the origin https://example.com to read responses made by AJAX` – SilverlightFox Oct 03 '22 at 18:30
  • @veita Adding the header doesn't cause any extra preflights, this is in the hands of the code on the calling domain. Whether cookies are sent are also under control of the calling site (and the browser ofc), eg. `withCredentials`. Non-CORS requests (ie. Those that could be sent via HTML only), send cookies as normal. Think about it, by the time the browser has read the headers it's too late, cookies have already been sent. – SilverlightFox Oct 03 '22 at 18:38
  • Ah good point about the *and* in your initial response. As for my comment regarding pre-flight - I meant the CORS standard itself introduces that, not a particular header. For example, now that we have the CORS standard, certain requests will pre-flight before initiating the request. If the server responds with "Access-Control-Allow-Origin: \*", the client will not send the request (nor the cookies) when it otherwise would have in a pre-cors era. My point being, the CORS standard seems to do more than relax SOP, as it prevents a request that would have initiated otherwise. – Veita Oct 04 '22 at 02:55
  • @Veita I understand what you're saying, but under the "pre-cors era" those requests wouldn't have been possible in the first place. That's why there is the pre-flight... These requests are now possible with extra headers, content types, etc, so the browser and the server need to make sure they both opt into CORS before they continue to communicate using the CORS specification. Therefore, CORS only relaxes cross domain communication Vs the "pre-cors era". – SilverlightFox Oct 04 '22 at 20:00
  • @SilverlightFox I could be wrong, but pre-cors, wouldn't the requests have been sent, but the response unreadable? Now, it seems the request isn't even sent to begin with. – Veita Oct 06 '22 at 02:26
  • @Veita No, the requests would not have been sent. Old browsers didn't support XHR cross-domain until CORS, except for IE8 in a very limited capacity which was even more restrictive than CORS. – SilverlightFox Oct 06 '22 at 09:06
117

CORS allows a site A to give permission to site B to read (potentially private) data from site A (using the visitor's browser and credentials).

CSP allows a site to prevent itself from loading (potentially malicious) content from unexpected sources (e.g. as a defence against XSS).

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • can CSP be used on site A to prevent site A from reading data from site B? I am talking mainly about xhr requests. – Vlas Bashynskyi Apr 10 '18 at 09:38
  • Can I say that CORS is a subset of what can be done with CSP ? – mathk Jan 16 '19 at 09:51
  • 2
    @mathk — No. As I said in the answer, they are completely different things. – Quentin Jan 16 '19 at 09:52
  • 1
    I mean if you do not allow the browser to download content from site B you will also guaranty that nothing will be sent to site B using CSP ? – mathk Jan 16 '19 at 09:59
  • 4
    @mathk — Site A preventing data being sent to Site B (which can be achieved with CSP) is completely different to Site B preventing Site A from reading data from it (which is the default behaviour but which can be relaxed with CORS). – Quentin Jan 16 '19 at 10:00
  • Are we agree that: `Site A preventing data being sent to Site B` -> Browser can not do a `GET[other verb] A`. and ` Site B preventing Site A from reading data from it ` Browser can not do a `POST B ` ? – mathk Jan 16 '19 at 10:06
  • @mathk — No. Nothing is stopping JS on site A triggering a post request to site B. The Same Origin Policy just stops site A's JavaScript from reading the response. – Quentin Jan 16 '19 at 10:10
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/186769/discussion-between-mathk-and-quentin). – mathk Jan 16 '19 at 10:11
  • When folks say these things are "completely different" that just makes the differences harder to understand because they aren't completely different. Same-origin policy (to which CORS is closely related) prevents reading cross-origin requests, the most common way a developer would come into contact with this policy. Likewise, one of the most common ways a developer would come into contact with CSP is because it is blocking cross-origin requests, e.g., in a greasemonkey script. – Michael Terry May 15 '19 at 20:14
  • If this simple and clear answer is correct, I wonder why MDN's documentation on this is so verbose and confusing. – Asker Jun 27 '23 at 23:28
  • @Asker — Because this is a one sentence summary of the purpose of each technology while MDN’s documentation is in-depth. – Quentin Jun 27 '23 at 23:59
  • @Quentin MDN's documentation as of this writing is missing such a summary, which is a shame--MDN leaves much to be desired in writing quality. Their articles are also not as deep as the WHATWG documentation. – Asker Jun 28 '23 at 03:51
  • @Asker — You could edit the MDN documentation if you think it can be improved. – Quentin Jun 28 '23 at 05:48
53

@JodySowald's comment, which I find more succinct:

Content-Security-Policy prevents calls to external resources and Cross-Origin-Resource-Sharing prevents calls from external sources. To provide an example. For example.com to show example.net in an iframe, example.com must not block example.net with its CSP settings and example.net must not block example.com with its CORS settings.


Original answer:

None of the answers above give a clear and concise difference between CSP and CORS. Here is my way of thinking about them:

Let's say we have example.com website that wants to send a request to example.net.

  1. When user visits example.com in browser, example.com server returns example.com HTTP response, CSP restriction within this response can prevent example.com in browser from issuing request to example.net.
  2. If there is no CSP restriction within example.com HTTP response, then example.com in browser can send a request to example.net.
  3. Upon receiving the request, example.net server responds with example.net HTTP response, CORS restriction within this response can prevent example.com in browser from loading it. (Note that by default, Same-origin policy will restrict the response from loading, unless otherwise specified by CORS)

So CSP protects example.com and same-origin policy (the lack of CORS) protects example.net in the example above.

Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
paradite
  • 6,238
  • 3
  • 40
  • 58
  • In this example, wouldn't the Same Origin policy protect **def.net**, whereas CORS removes this protection if enabled? – Steve Apr 06 '19 at 17:37
  • @Steve you are right, it's kind of a misnomer, I've updated my answer to reflect it. – paradite Apr 07 '19 at 07:06
  • 11
    Is it a correct simplification to say that Content-Security-Policy prevents calls to external resources and Cross-Origin-Resource-Sharing prevents calls from external sources? to provide an example. For abc.com to show def.net in an iframe, abc.com must not block def.net with its CSP settings and def.net must not block abc.com with its CORS settings. – Jody Sowald Mar 06 '20 at 18:26
  • 2
    @JodySowald that would seem fitting. – paradite Jan 06 '21 at 13:25
3

CORS checks with the third party for authorization to use its services. So, the third party provides or denies authorization.

So for example if a page in www.example.com needs to make a request to www.example.org, the browser sends an OPTIONS request with Origin: www.example.com as a precursor to request for authorization. Now, www.example.org provides or denies authorization.

CSP prevents a webpage from inadvertently loading malicious content from a third party by specifying where a particular type of content can be loaded from. So, for example you can provide a valid source for each of the following scripts, css, media etc. by using directives

Example:

Content-Security-Policy: default-src 'none'; script-src 'self' www.google-analytics.com ajax.googleapis.com; connect-src 'self'; img-src 'self'; style-src 'self';
Cees Timmerman
  • 17,623
  • 11
  • 91
  • 124
sbdh shvpj
  • 31
  • 3
0

Cross-Origin Resource Sharing (CORS)

A response header that tells the browser to only allow specific sources access to your content, e.g.:

Access-Control-Allow-Origin: https://onlinebanking.example.com

CORS was invented in 2004 and won't stop your content from talking to strangers and using replies for *, so since 2013 we have:

Content Security Policy (CSP)

A response header that tells the browser to only allow specific sources to be accessed from the content:

Content-Security-Policy: default-src https://onlinebanking.example.com

That can also be set or tightened via HTML:

<meta
  http-equiv="Content-Security-Policy"
  content="default-src https://onlinebanking.example.com" />
Cees Timmerman
  • 17,623
  • 11
  • 91
  • 124