什么时候启用 CORS 是安全的?

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

Access-Control-Allow-Origin: *

它允许第三方网站通过 AJAX 调用我的服务。到目前为止一切正常。

然而,我的 web api 的一部分是非公开的,需要身份验证(OAuth 和 access _ token cookie 的标准配置)。在我的站点的这个部分启用 CORS 是否安全?

一方面,如果第三方网站可以有 ajax 客户端,也与我的服务这一部分的互动,这将是很酷的。然而,之所以有一个相同的原产地政策摆在首位,是因为这可能是有风险的。你不希望任何网站,你访问后,能够访问您的私人内容。

我担心的情况是,用户登录我的 web api,无论是在网站上还是通过他信任的网站,然后他忘记注销。这是否允许其他网站,他后来积极访问他的私人内容使用现有的会议?

所以我的问题是:

  • 在非公共内容上启用 CORS 是否安全?
  • 如果启用 CORS 的服务器通过 Cookie 设置会话令牌,这个 Cookie 会保存在 CORS 服务器或主网页服务器的域下吗?
51201 次浏览

The intention of CORS is to allow cross-origin requests for XHR requests while giving the server the authority to specify what origin has access to which resource. In particular, CORS introduced the Origin header field that allows the server to tell regular and possible XHR requests apart. This header field cannot be set or changed by the user but is set by the browser for XHR requests.

So if you have an API that is designed to be only used by XHR, you can (and should) require the request to conform with CORS. Especially if the requests can also modify state on your server as otherwise you would be vulnerable to CSRF.

Note the CSRF attacks are possible regardless of CORS using other methods to forge GET and POST requests. CORS does only enable to access the server’s response of XHR requests with JavaScript if the server allows it.

In answer to your second question (If a CORS enabled server sets a session_token through a cookie...?), the cookie is saved under the domain of the CORS server. The main web page's JS code can't access the cookie, even via document.cookie. The cookie is only sent to the server when the .withCredentials property is set, and even then, it is only accepted when the server sets the Access-Control-Allow-Credentials header.

Your first question is a little more open ended. It is fairly secure, but there are ways to circumvent things. For example, an attacker could use a DNS poisoning technique to cause a preflight request to hit the actual server, but send the actual CORS request to the rogue server. Here are some more resources on CORS security:

Lastly, your concern is around giving any website access to your CORS data. In order to protect against this, you should not use the Access-Control-Allow-Origin: * header. Instead, you should echo back the user's Origin value. For example:

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

This header will allow only http://www.example.com to access the response data.