跨域资源共享(CORS)——我在这里遗漏了什么吗?
我正在阅读有关 CORS 的内容,我认为实现既简单又有效。
然而,除非我遗漏了什么,否则我认为规范中遗漏了很大一部分。据我了解,外国站点根据请求的来源(以及可选的包括凭据)决定是否允许访问其资源。这很好。
但是,如果页面上的恶意代码想要将用户的敏感信息发布到国外站点怎么办?外国网站显然会验证该请求。因此,如果我没有遗漏什么的话,CORS 实际上使窃取敏感信息变得更容易。
我认为,如果原始站点还可以提供允许其页面访问的不可变服务器列表,那就更有意义了。
因此,扩展序列将是:
- 提供一个包含可接受的 CORS 服务器列表(abc.com、xyz.com 等)的页面
- 页面想要向 abc.com 发出 XHR 请求 - 浏览器允许这样做,因为它位于允许的列表中并且身份验证按正常方式进行
- Page 想要向恶意.com 发出 XHR 请求 - 请求在本地被拒绝(即被浏览器拒绝),因为服务器不在列表中。
我知道恶意代码仍然可以使用 JSONP 来完成其肮脏的工作,但我本以为 CORS 的完整实现将意味着脚本标记多站点漏洞的关闭。
我还查看了官方 CORS 规范 (http://www.w3.org/TR/cors)并且找不到任何提及此问题的信息。
I was reading about CORS and I think the implementation is both simple and effective.
However, unless I'm missing something, I think there's a big part missing from the spec. As I understand, it's the foreign site that decides, based on the origin of the request (and optionally including credentials), whether to allow access to its resources. This is fine.
But what if malicious code on the page wants to POST a user's sensitive information to a foreign site? The foreign site is obviously going to authenticate the request. Hence, again if I'm not missing something, CORS actually makes it easier to steal sensitive information.
I think it would have made much more sense if the original site could also supply an immutable list of servers its page is allowed to access.
So the expanded sequence would be:
- Supply a page with list of acceptable CORS servers (abc.com, xyz.com, etc)
- Page wants to make an XHR request to abc.com - the browser allows this because it's in the allowed list and authentication proceeds as normal
- Page wants to make an XHR request to malicious.com - request rejected locally (ie by the browser) because the server is not in the list.
I know that malicious code could still use JSONP to do its dirty work, but I would have thought that a complete implementation of CORS would imply the closing of the script tag multi-site loophole.
I also checked out the official CORS spec (http://www.w3.org/TR/cors) and could not find any mention of this issue.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
那又怎样呢?无需 CORS,您已经可以做到这一点。即使早在 Netscape 2 中,您就始终能够通过
form.submit()
、等简单接口引发的简单 GET 和 POST 请求将信息传输到任何第三方站点。新图像
或设置window.location
。如果恶意代码能够访问敏感信息,那么您就已经彻底失败了。
为什么页面会尝试向尚未列入白名单的网站发出 XHR 请求?
如果您试图防止由于 XSS 漏洞而注入的恶意脚本的操作,那么您只是在尝试修复症状,而不是修复原因。
What about it? You can already do that without CORS. Even back as far as Netscape 2, you have always been able to transfer information to any third-party site through simple GET and POST requests caused by interfaces as simple as
form.submit()
,new Image
or settingwindow.location
.If malicious code has access to sensitive information, you have already totally lost.
Why would a page try to make an XHR request to a site it has not already whitelisted?
If you are trying to protect against the actions of malicious script injected due to XSS vulnerabilities, you are attempting to fix the symptom, not the cause.
你的担心是完全有道理的。
然而,更令人担忧的是,不需要存在任何恶意代码就可以利用这一点。有许多基于 DOM 的跨站点脚本漏洞,允许攻击者利用您所描述的问题并将恶意 JavaScript 插入易受攻击的网页中。问题不仅仅是可以向何处发送数据,还在于可以从何处接收数据。
我在这里更详细地讨论这一点:
Your worries are completely valid.
However, more worrisome is the fact that there doesn't need to be any malicious code present for this to be taken advantage of. There are a number of DOM-based cross-site scripting vulnerabilities that allow attackers to take advantage of the issue you described and insert malicious JavaScript into vulnerable webpages. The issue is more than just where data can be sent, but where data can be received from.
I talk about this in more detail here:
在我看来,CORS 纯粹是在扩展可能性,并试图安全地做到这一点。我认为这显然是一个保守的举动。对其他标签(脚本/图像)制定更严格的跨域策略,同时更安全,会破坏大量现有代码,并使采用新技术变得更加困难。希望能够采取一些措施来弥补这个安全漏洞,但我认为他们首先需要确保它是一个简单的过渡。
It seems to me that CORS is purely expanding what is possible, and trying to do it securely. I think this is clearly a conservative move. Making a stricter cross domain policy on other tags (script/image) while being more secure, would break a lot of existing code, and make it much more difficult to adopt the new technology. Hopefully, something will be done to close that security hole, but I think they need to make sure its an easy transition first.
我还查看了官方 CORS 规范,但找不到任何提及此内容的内容问题。
对。 CORS 规范正在解决一个完全不同的问题。您错误地认为它会使问题变得更糟 - 它不会使问题变得更好也不会变得更糟,因为一旦恶意脚本在您的页面上运行,它就已经可以将数据发送到任何地方。
不过,好消息是,有一个广泛实施的解决此问题的 规范:Content-Security-Policy 。它允许您指示浏览器对页面的功能进行限制。
例如,您可以告诉浏览器不要执行任何内联脚本,这将立即击败许多 XSS 攻击。或者,正如您在此处所请求的那样,您可以明确告诉浏览器允许该页面联系哪些域。
I also checked out the official CORS spec and could not find any mention of this issue.
Right. The CORS specification is solving a completely different problem. You're mistaken that it makes the problem worse - it makes the problem neither better nor worse, because once a malicious script is running on your page it can already send the data anywhere.
The good news, though, is that there is a widely-implemented specification that addresses this problem: the Content-Security-Policy. It allows you to instruct the browser to place limits on what your page can do.
For example, you can tell the browser not to execute any inline scripts, which will immediately defeat many XSS attacks. Or—as you've requested here—you can explicitly tell the browser which domains the page is allowed to contact.
问题不在于一个站点可以访问它已经有权访问的另一个站点的资源。问题是域之一——如果我在公司使用浏览器,并且 ajax 脚本恶意决定尝试 10.0.0.1(可能是我的网关),它可能会访问,因为请求现在来自我的计算机(可能是 10.0.0.2)。
所以解决方案——CORS。我并不是说它是最好的,但它解决了这个问题。
1) 如果网关无法返回“bobthehacker.com”接受的原始标头,则请求将被浏览器拒绝。。这可以处理旧的或未准备好的服务器。
2) 如果网关仅允许来自 myinternaldomain.com 域的项目,它将拒绝“bobthehacker.com”的 ORIGIN。在 SIMPLE CORS 情况下,它实际上仍然会返回结果。默认情况下;您甚至可以将服务器配置为不这样做。然后结果将被丢弃,浏览器不会加载。
3) 最后,即使它接受某些域,您也可以对接受和拒绝的标头进行一些控制,以使来自这些站点的请求符合特定的形状。
注意 - ORIGIN 和 OPTIONS 标头由请求者控制 - 显然,创建自己的 HTTP 请求的人可以在其中放置他们想要的任何内容。然而现代的 CORS 兼容浏览器不会这样做。控制交互的是浏览器。浏览器阻止 bobthehacker.com 访问网关。这就是你所缺少的部分。
The problem isn't that a site can access another sites resources that it already had access to. The problem is one of domain -- If I'm using a browser at my company, and an ajax script maliciously decides to try out 10.0.0.1 (potentially my gateway), it may have access simply because the request is now coming from my computer (perhaps 10.0.0.2).
So the solution -- CORS. I'm not saying its the best, but is solves this issue.
1) If the gateway can't return back the 'bobthehacker.com' accepted origin header, the request is rejected by the browser. This handles old or unprepared servers.
2) If the gateway only allows items from the myinternaldomain.com domain, it will reject an ORIGIN of 'bobthehacker.com'. In the SIMPLE CORS case, it will actually still return the results. By default; you can configure the server to not even do that. Then the results are discarded without being loaded by the browser.
3) Finally, even if it would accept certain domains, you have some control over the headers that are accepted and rejected to make the request from those sites conform to a certain shape.
Note -- the ORIGIN and OPTIONS headers are controlled by the requester -- obviously someone creating their own HTTP request can put whatever they want in there. However a modern CORS compliant browser WONT do that. It is the Browser that controls the interaction. The browser is preventing bobthehacker.com from accessing the gateway. That is the part you are missing.
我和大卫有同样的担忧。
安全性必须逐层构建,由源服务器提供的白名单似乎是一个好方法。
另外,这个白名单可以用来堵住现有的漏洞(表单、脚本标签等),可以安全地假设服务白名单的服务器旨在避免向后兼容性问题。
I share David's concerns.
Security must be built layer by layer and a white list served by the origin server seems to be a good approach.
Plus, this white list can be used to close existing loopholes (forms, script tag, etc...), it's safe to assume that a server serving the white list is designed to avoid back compatibility issues.