我正在开发一个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服务器或主网页服务器的域下吗
在回答第二个问题时(如果启用CORS的服务器通过cookie设置session_token…?),cookie将保存在CORS服务器的域下。主网页的JS代码无法访问cookie,即使是通过document.cookie
。只有在设置了.withCredentials
属性时,cookie才会发送到服务器,即便如此,也只有在服务器设置了Access-Control-Allow-Credentials
标头时,cookie才被接受。
你的第一个问题比较开放。它是相当安全的,但有一些方法可以绕过它。例如,攻击者可以使用DNS中毒技术导致飞行前请求命中实际服务器,但将实际的CORS请求发送给流氓服务器。以下是关于CORS安全的更多资源:
- http://code.google.com/p/html5security/wiki/CrossOriginRequestSecurity
- owasp.org CORS备忘单
最后,您关心的是让任何网站访问您的CORS数据。为了防止出现这种情况,您不应该使用Access-Control-Allow-Origin: *
标头。相反,您应该回显用户的Origin值。例如:
Access-Control-Allow-Origin: http://www.example.com
此标头将仅允许http://www.example.com
访问响应数据。
CORS的目的是允许XHR请求的跨来源请求,同时赋予服务器指定哪个来源可以访问哪个资源的权限。特别是,CORS引入了Origin头字段,该字段允许服务器区分常规请求和可能的XHR请求。此标头字段不能由用户设置或更改,而是由浏览器为XHR请求设置的。
因此,如果您有一个API设计为仅由XHR使用,那么您可以(也应该)要求请求符合CORS。特别是如果请求也可以修改服务器上的状态,否则您将容易受到CSRF的攻击。
请注意,无论CORS使用其他方法伪造GET和POST请求,CSRF攻击都是可能的。CORS只允许在服务器允许的情况下使用JavaScript访问服务器对XHR请求的响应。