跨域资源共享 (CORS) - 我在这里遗漏了啥吗?
Posted
技术标签:
【中文标题】跨域资源共享 (CORS) - 我在这里遗漏了啥吗?【英文标题】:Cross-Origin Resource Sharing (CORS) - am I missing something here?跨域资源共享 (CORS) - 我在这里遗漏了什么吗? 【发布时间】:2011-02-01 17:55:58 【问题描述】:我正在阅读有关 CORS 的信息,我认为实现既简单又有效。
但是,除非我遗漏了什么,否则我认为规范中遗漏了很大一部分。据我了解,是外部站点根据请求的来源(并且可以选择包括凭据)决定是否允许访问其资源。这很好。
但是如果页面上的恶意代码想要将用户的敏感信息发布到外部站点怎么办?外部站点显然要对请求进行身份验证。因此,如果我没有遗漏什么,CORS 实际上可以更轻松地窃取敏感信息。
我认为,如果原始站点也可以提供其页面允许访问的服务器的不可变列表,那将更有意义。
所以扩展的序列将是:
-
提供包含可接受 CORS 服务器(abc.com、xyz.com 等)列表的页面
页面想要向 abc.com 发出 XHR 请求 - 浏览器允许这样做,因为它在允许列表中并且身份验证正常进行
页面想要向恶意网站发出 XHR 请求 - 请求在本地被拒绝(即被浏览器拒绝),因为服务器不在列表中。
我知道恶意代码仍然可以使用 JSONP 来完成它的肮脏工作,但我原以为 CORS 的完整实现将意味着脚本标签多站点漏洞的关闭。
我还查看了官方 CORS 规范 (http://www.w3.org/TR/cors),但找不到任何关于此问题的提及。
【问题讨论】:
【参考方案1】:在我看来,CORS 纯粹是在扩展可能性,并试图安全地做到这一点。我认为这显然是一个保守的举动。在更安全的同时对其他标签(脚本/图像)制定更严格的跨域策略会破坏大量现有代码,并使采用新技术变得更加困难。希望可以采取一些措施来弥补这个安全漏洞,但我认为他们需要先确保它能够轻松过渡。
【讨论】:
我的主要观点不是关闭当前的漏洞,而是事实上(至少在我看来)CORS 规范中存在一个大漏洞。【参考方案2】:但是如果页面上的恶意代码想要将用户的敏感信息发布到外部站点怎么办?
怎么样?你已经可以在没有 CORS 的情况下做到这一点。甚至早在 Netscape 2 中,您始终能够通过简单的 GET 和 POST 请求将信息传输到任何第三方站点,这些请求由简单的接口(如form.submit()
、new Image
或设置window.location
)引起。
如果恶意代码可以访问敏感信息,你就已经完全迷失了。
3) 页面想要向恶意网站发出 XHR 请求 - 请求被本地拒绝
为什么页面会尝试向尚未列入白名单的网站发出 XHR 请求?
如果您试图防止由于 XSS 漏洞而注入的恶意脚本的行为,那么您是在尝试修复症状,而不是原因。
【讨论】:
同意 - 但肯定希望让受损页面难以将信息写入非白名单位置。我不认为它对结果而不是原因起作用。一个好的银行金库仍然会试图让劫匪很难将钱取出,即使他们确实设法击败了第一级安全并首先进入了金库。 无效的安全措施比没有安全措施更糟糕。 “一个好的银行保险库仍然会试图让劫匪很难把钱取出来,即使他们确实设法击败了第一级安全”即使是最好的银行保险库也不会费心安装,例如,一个钢屏障,知道小偷唯一要做的就是绕过屏障。正如 bobince 所说,一旦你有 XSS 漏洞,你就已经完全迷失了。 您本可以更直接地解决 OP 的误解:CORS 不会缓解 XSS,而是启用它。【参考方案3】:我同意大卫的担忧。 必须逐层构建安全性,由源服务器提供的白名单似乎是一个不错的方法。
此外,此白名单可用于关闭现有漏洞(表单、脚本标签等),可以肯定地假设为白名单提供服务的服务器旨在避免向后兼容性问题。
【讨论】:
不幸的是,CSRF 漏洞已融入 Web 的基本架构中。现在改不了了。即使它可以改变,也不清楚它应该改变。是的,存在安全问题,但安全并不是宏伟计划中的唯一考虑因素。【参考方案4】:你的担心完全有道理。
然而,更令人担忧的是,不需要任何恶意代码就可以利用这一点。有许多基于 DOM 的跨站点脚本漏洞允许攻击者利用您描述的问题并将恶意 javascript 插入易受攻击的网页。问题不仅仅是可以发送数据的位置,而是可以从哪里接收数据。
我在这里更详细地讨论这个:
http://isisblogs.poly.edu/2011/06/22/cross-origin-resource-inclusion/ http://files.meetup.com/2461862/Cross-Origin%20Resource%20Inclusion%20-%20Revision%203.pdf【讨论】:
【参考方案5】:我也查了官方CORS spec,也没有找到任何关于这个问题的提及。
没错。 CORS 规范正在解决一个完全不同的问题。您误认为它使问题变得更糟 - 它使问题既不好也不坏,因为一旦恶意脚本在您的页面上运行,它就已经可以将数据发送到任何地方。
不过,好消息是有一个widely-implemented 规范可以解决这个问题:Content-Security-Policy。它允许您指示浏览器限制您的页面可以执行的操作。
例如,您可以告诉浏览器不要执行任何内联脚本,这将立即击败许多 XSS 攻击。或者——正如你在此处所要求的——你可以明确地告诉浏览器允许该页面联系哪些域。
【讨论】:
【参考方案6】:问题不在于一个站点可以访问它已经有权访问的另一个站点资源。问题是域之一 - 如果我在我的公司使用浏览器,并且 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 访问网关。这就是你缺少的部分。
【讨论】:
以上是关于跨域资源共享 (CORS) - 我在这里遗漏了啥吗?的主要内容,如果未能解决你的问题,请参考以下文章
我的代码看起来很完美,但显示错误的输出。有人可以帮我我在这里做错了啥吗?
有人能告诉我在objective-c中保留和释放到底做了啥吗?
使用`setVariables`后中继生成无效查询-我做错了啥吗?