CORS和CSPs之间有什么区别?

125
从我的角度来看,所谓的“跨域资源共享(CORS)”和“内容安全策略(CSP)”这两种技术在目的和实现上似乎非常相似。
两者似乎都允许您通过HTTP响应头白名单来批准未被篡改的网页所包含的资源的来源。我唯一能看出的区别是CSP似乎在您可以批准的HTTP响应中更加细致。
5个回答

139

CORS允许对域名放宽同源策略

例如,通常情况下,如果用户同时登录example.comexample.org,同源策略会阻止example.comexample.org/current_user/full_user_details发出AJAX请求并获取响应的权限。

这是Web的默认策略,可以防止用户在同时登录多个站点时泄露数据。

现在,有了CORS,example.org可以设置一个策略,表示它将允许来自AJAX的https://example.com来源读取响应。如果example.comexample.org由同一公司运营,并且希望在用户的浏览器中允许这些来源之间共享数据,则可以执行此操作。它只影响客户端,而不影响服务器端。

CSPs则制定了当前网站上可以运行哪些内容的策略。例如,JavaScript是否可以内联执行,或者可以从哪些域名加载.js文件。这可以作为另一道防线来防御XSS攻击,其中攻击者会尝试将脚本注入HTML页面。通常输出将被编码,但是假设开发人员只忘记了一个输出字段。由于该策略阻止了内联脚本的执行,因此攻击被挫败了。

9
比起所有的Mozilla/HTML5Rocks/W3C文档,这篇文章更加清晰明了,直截了当。谢谢。 - JepZ
这并不完全正确 - 同源策略默认情况下不会防止 AJAX 请求。 它只会阻止浏览器访问操作结果。 此外,CORS 不仅可以放宽SOP,还可以进一步限制 - 例如当“\ ”用作“Access-Control-Allow-Origin”标头时,浏览器将不会*发送 cookie,并且它将预先处理某些请求。 - Veita
关于你最初回答中的 and,说得好。至于我关于预检请求的评论 - 我指的是CORS标准本身引入了这个概念,而不是特定的头部。例如,现在我们有了CORS标准,某些请求将在发起请求之前进行预检。如果服务器响应 "Access-Control-Allow-Origin: *",则客户端将不会在以前的CORS时代发送请求(也不会发送cookie)。我的观点是,CORS标准似乎做得更多,不仅放宽了SOP,还防止了一个本来会发起的请求。 - Veita
@Veita 我明白你的意思,但在“pre-cors时代”,这些请求本来就不可能实现。这就是为什么有预检请求...现在这些请求可以通过额外的头部、内容类型等实现,因此浏览器和服务器需要确保它们都选择CORS才能继续使用CORS规范进行通信。因此,CORS只是相对于“pre-cors时代”放松了跨域通信。 - SilverlightFox
@Veita 不会发送请求。在 CORS 出现之前,旧版浏览器不支持 XHR 跨域,除了 IE8 以非常有限的方式支持,而且比 CORS 更加限制。 - SilverlightFox
显示剩余3条评论

117

CORS允许站点A授权站点B读取(可能是私有的)来自站点A的数据(使用访问者的浏览器和凭据)。

CSP允许网站防止它自己从意外来源(例如,作为防御XSS的措施)加载(可能是恶意的)内容。


我可以说CORS是CSP所能做的事情的一个子集吗? - mathk
2
@mathk — 不是。正如我在答案中提到的,它们是完全不同的东西。 - Quentin
1
我的意思是,如果您不允许浏览器从B站点下载内容,那么使用CSP也可以保证不会向B站点发送任何内容吗? - mathk
4
@mathk 提到通过内容安全策略(CSP),Site A 可以防止数据被发送到 Site B,这与 Site B 防止 Site A 从其读取数据(这是默认行为,但可以通过跨域资源共享(CORS)进行放宽)完全不同。 - Quentin
我们是否认同以下内容:网站A阻止数据被发送到网站B -> 浏览器无法执行 GET[其他动词] A。以及 网站B阻止网站A读取其数据 -> 浏览器无法执行 POST B <一些数据> - mathk
显示剩余8条评论

53

以下是JodySowald的简明评论:

内容安全策略(CSP)会阻止对外部资源的调用,跨源资源共享(CORS)会阻止来自外部来源的调用。举个例子,在example.com中展示example.net的iframe,example.com不能使用其CSP设置阻止example.net,而example.net也不能使用其CORS设置阻止example.com


原始回答:

上面的回答没有给出CSP和CORS之间的清晰而简洁的区别。以下是我的思考方式:

假设我们有一个想要发送请求到example.netexample.com网站。

  1. 当用户在浏览器中访问example.com时,example.com服务器返回example.com HTTP响应,此响应中的CSP限制可以防止浏览器中的example.comexample.net发出请求。
  2. 如果example.com HTTP响应中没有CSP限制,则浏览器中的example.com可以向example.net发送请求。
收到请求后,example.net 服务器会响应example.net HTTP 响应,响应中的CORS限制可能会阻止浏览器中的example.com 加载它。(请注意,默认情况下,Same-origin policy将限制响应的加载,除非通过CORS另有规定)
因此,以上示例中CSP保护了example.com,而同源策略(缺少CORS)则保护了example.net

在这个例子中,如果启用了CORS,Same Origin策略会保护def.net吗? - Steve
@Steve,你说得对,这有点不准确,我已经更新了我的答案来反映它。 - paradite
11
Content-Security-Policy(内容安全策略)可以阻止对外部资源的调用,而Cross-Origin-Resource-Sharing(跨域资源共享)可以防止来自外部源的调用。举个例子,如果abc.com要在iframe中显示def.net,则abc.com不能使用其CSP设置阻止def.net,同时def.net也不能使用其CORS设置阻止abc.com。 - Jody Sowald
2
@JodySowald 看起来似乎很合适。 - paradite

3

CORS检查与第三方的授权以使用其服务。因此,第三方提供或拒绝授权。

例如,如果www.example.com中的页面需要向www.example.org发出请求,则浏览器发送一个具有Origin: www.example.comOPTIONS请求作为请求授权的前置条件。现在,www.example.org提供或拒绝授权。

CSP通过指定可以从哪里加载特定类型的内容来防止网页不经意地从第三方加载恶意内容。因此,例如,您可以使用指令为以下每个脚本、CSS、媒体等提供有效的源。

示例:

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';

0

跨域资源共享(CORS)

一种响应头,告诉浏览器只允许特定来源访问您的内容,例如:

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

CORS是2004年发明的,它不会阻止您的内容与陌生人交流并使用*进行回复,因此自2013年以来我们有:

内容安全策略(CSP)

一种响应头,告诉浏览器只允许从特定来源访问内容:

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

这也可以通过HTML进行设置或收紧:

<meta
  http-equiv="Content-Security-Policy"
  content="default-src https://onlinebanking.example.com" />

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接