什么时候可以安全启用CORS?


77

我正在开发JSON / REST Web API,为此,我特别希望第三方网站能够通过AJAX调用我的服务。因此,我的服务正在发送著名的CORS标头:

Access-Control-Allow-Origin: *

允许第三方站点通过AJAX调用我的服务。到目前为止一切都很好。

但是,我的Web api的一个子部分是非公开的,需要身份验证(带有OAuth和access_token cookie的相当标准的东西)。在我网站的此部分也启用CORS是否安全?

一方面,如果第三方网站可以具有也与我的服务的这一部分进行交互的ajax客户端,那将很酷。但是,首先要有一个相同的原产地政策的原因是这样做可能有风险。您不希望以后访问的任何网站都能够访问您的私人内容。

我担心的情况是,用户在网站或他信任的网站上登录我的Web api,却忘记了注销。这会允许他随后访问的所有其他网站使用现有会话访问其私人内容吗?

所以我的问题是:

  • 在非公开内容上启用CORS是否安全?
  • 如果启用了CORS的服务器通过cookie设置了session_token,该cookie是否保存在CORS服务器或主网页服务器的域下?

2
请注意,您只能在您希望其他人从其他来源访问的资源上发送CORS标头。而且,您也可以将CORS的访问权限限制为仅希望使用的来源。
Dan D.

1
从概念上讲,如果安全允许,我希望所有资源都可以从任何来源访问。用户仍然需要提供有效的凭据。我只想确保我没有为恶意网站的跨站点脚本攻击打开大门。
耶隆

Answers:


45

在回答您的第二个问题(如果启用了CORS的服务器通过cookie设置了session_token ...?)时,该cookie将保存在CORS服务器的域下。网页的JS代码即使通过也无法访问cookie document.cookie。cookie仅在.withCredentials设置了属性时才发送到服务器,即使这样,也只有在服务器设置Access-Control-Allow-Credentials标头时才接受。

您的第一个问题是更多开放的话题。它是相当安全的,但是有一些规避事物的方法。例如,攻击者可能使用DNS中毒技术,使预检请求命中实际服务器,但将实际CORS请求发送到恶意服务器。以下是有关CORS安全性的更多资源:

最后,您担心的是允许任何网站访问您的CORS数据。为了防止这种情况,您不应使用Access-Control-Allow-Origin: *标题。而是应回显用户的Origin值。例如:

Access-Control-Allow-Origin: http://www.example.com

该头仅允许http://www.example.com访问响应数据。


4
您能否阐明回显“ origin”标头如何增加安全性?我认为任何恶意网站/脚本都可以轻松设置此标头吗?还是您要维护某种白名单?
耶隆

5
是的,保持可接受来源的白名单是一种解决方案。另一个是将用户会话ID绑定到特定来源。这样,如果其他来源以某种方式使用用户的凭据重播请求,它将失败。
monsur 2012年

我认为您的意思是说攻击者将拦截预检,而不是实际的请求。另请注意,GET未预先显示。
csauve 2012年

3
如果GET包含非简单的请求标头,则可以进行预检。
monsur 2012年

1
@Jeroen根据CORS规范,任何恶意网站/脚本都可以设置Origin标头,这是一个误解,因为标头是“禁止的”标头:fetch.spec.whatwg.org/#forbidden-header-name
Peter Thomassen

25

CORS的目的是允许XHR请求的跨域请求,同时赋予服务器权限以指定哪个源可以访问哪个资源。特别是,CORS引入了Origin头字段,该字段使服务器可以区分常规的XHR请求和可能的XHR请求。该标头字段不能由用户设置或更改,而是由浏览器为XHR请求设置。

因此,如果您具有仅供XHR使用的API,则可以(并且应该)要求该请求符合CORS。特别是如果请求还可以修改服务器上的状态,否则您将很容易受到CSRF的攻击。

请注意,无论CORS是否使用其他方法伪造GET和POST请求,CSRF攻击都是可能的。如果服务器允许,CORS仅允许使用JavaScript访问服务器对XHR请求的响应。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.