何时启用 CORS 是安全的?

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

I am developing a JSON/REST web API, for which I specifically want third party websites to be able to call my service through AJAX. Hence, my service is sending the famous CORS header:

Access-Control-Allow-Origin: *

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

Which allows third party sites to call my service through AJAX. All fine so far.

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

However, a subsection of my web api is non-public and requires authentication (pretty standard stuff with OAuth and an access_token cookie). Is it safe to enable CORS on this part of my site as well?

一方面,如果第三方网站可以拥有与我的这部分服务进行交互的 ajax 客户端,那就太棒了.但是,首先存在同源策略的原因是,这可能是有风险的.您不希望您之后访问的任何网站都能够访问您的私人内容.

On the one hand, it would be cool if third party websites could have ajax clients that also interact with this part of my service. However, the reason that there is a same origin policy in the first place, is that this might be risky. You don't want any website that you visit afterwards to be able to access your private content.

我害怕的场景是用户在我的 web api 上登录,无论是在网站上还是通过他信任的网站,他都忘记了注销.这是否允许他之后访问的所有其他网站使用现有会话访问他的私人内容?

The scenario that I am afraid of is that a user logs in on my web api, either on the website or through a website that he trusts, and he forgets to logout. Will this allow every other website that he vists afterwards to access his private content using the existing session?

所以我的问题:

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

推荐答案

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

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.

您的第一个问题比较开放.这是相当安全的,但有一些方法可以规避事情.例如,攻击者可以使用 DNS 中毒技术导致预检请求命中实际服务器,但将实际 CORS 请求发送到流氓服务器.以下是有关 CORS 安全性的更多资源:

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:

  • http://code.google.com/p/html5security/wiki/CrossOriginRequestSecurity
  • owasp.org CORS CheatSheet

最后,您关心的是让任何网站访问您的 CORS 数据.为了防止这种情况,您不应使用 Access-Control-Allow-Origin: * 标头.相反,您应该回显用户的 Origin 值.例如:

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

此标头将只允许 http://www.example.com 访问响应数据.

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

相关文章