关于跨源资源共享(CORS)如何工作的困惑

时间:2014-12-20 18:36:11

标签: javascript jquery cross-domain cors

根据我对CORS的理解,这是它的工作原理:我有一个网站foo.com,它提供页面X.X想要将数据发布到另一个域bar.com。如果bar.com启用了CORS(其标题生成Access-Control-Allow-Origin foo.com),则页面X现在可以将数据发送到bar.com。

据我了解要让CORS工作,所有这些都是关于在bar.com上设置的,与foo.com无关。这一切都是为了确保bar.com不接受任何旧域名的请求。

然而,真的对我来说没有意义。我认为CORS的目的是让foo.com能够决定允许哪些X与之通信。如果我们回到前面的例子,但这次X被狡猾的脚本破坏,以便它秘密地向evil.com发送数据,CORS将如何阻止它? evil.com已启用CORS,并设置为*,因此它将接受来自任何内容的请求。这样一来,用户认为他们使用网站foo.com,就会无意中将数据发送到evil.com。

如果真的关于bar.com保护自己,那为什么它会让浏览器强制执行该策略?唯一可以想象的情况是,如果你让evil.com服务于冒充foo.com的页面Y,那就试图将数据发送到bar.com。但是CORS是由浏览器强制执行的,你所要做的就是让evil.com成为将伪造的原始请求发送到bar.com的代理(数据从Y发送到evil.com,evil.com设置它的假源到foo.com然后发送到bar.com)。

如果它以相反的方式工作,那对我来说才有意义。 foo.com启用了CORS,其标头设置为Access-Control-Allow-Origin bar.com。这样,胭脂脚本将被浏览器拒绝访问evil.com。然后,浏览器强制执行策略是有意义的,因为它运行的脚本可能会变成胭脂。它不会阻止胭脂网站尝试将胭脂数据发送到bar.com,但bar.com可以使用用户名/密码保护自己。如果foo.com的端点是它期望从X返回数据,那么你可以将令牌嵌入到X中,以确保evil.com不会向其发送数据。

我觉得我在这里不了解一些根本重要的东西。真的很感激帮助。

2 个答案:

答案 0 :(得分:4)

  

然而,这对我来说真的没有意义。我认为CORS的目的是让foo.com能够决定允许X与谁通信。

不,它是关于控制其内容使用的 bar.com

  

但是,CORS是由浏览器强制执行的,您所要做的就是让evil.com成为将伪造的原始请求发送到bar.com的代理...

烨。如果您这样做,并且bar.com上的人员会注意并关心他们,他们会拒绝来自您服务器的请求。你移动它,他们不允许新的。哇鼹鼠的时间。但令人痛苦的是,如果请求直接来自foo.com的每个用户来自他们的桌面,那么它的痛苦要小得多。

让foo.com强制执行foo.com所能做的事情并没有任何意义。 foo.com 已经强制执行foo.com可以执行的操作,因为它是为foo.com的内容和脚本提供服务的foo.com。

答案 1 :(得分:2)

不是关于Foo.com,也不是关于Bar.com。这是关于用户。

CORS有两件事可以防范。首先是访问防火墙后面的资源。第二种是通常受保护的资源,除非从具有身份验证或其他敏感数据cookie的浏览器发送请求。

CORS是一种浏览器技术,在服务器的支持下,允许foo在其域外调用的自由度有限。这是对跨域脚本限制的限制性漏洞。

任何人都可以伪造ORIGIN标头并创建一个CORS预检或简单请求 - 当然,任何人都可以直接连接到Bar服务器并在不使用CORS的情况下发出请求。任何浏览器都可以直接连接到bar.com并获取数据。但是现代浏览器不会运行访问bar.com资源的foo.com脚本。访问网站的人员不会访问旨在利用cookie的网站或浏览器位于公司防火墙后面的事实。

所以接受的答案是错误的。它并不是关于bar.com保护其资源的 - 它通过身份验证和授权来实现。您不必创建代理来发送CORS请求 - 您创建一个代理来剥离CORS请求(自动响应预检请求,并将正确的标头返回到浏览器,但发送正常请求到bar.com)。但是你仍然需要身份验证来获取bar.com的资源,而且foo.com仍然需要以某种方式让你安装代理来利用CORS保护的跨域脚本漏洞。

但最后的句子是正确的 - foo.com不能控制资源 - 它是浏览器,快速检查bar.com以询问它是否是预期的。

来自OP:

  

如果真的是关于bar.com保护自己,那为什么呢   让浏览器执行策略?唯一可以想象的情况   如果你有evil.com服务于页面Y,这是有道理的   冒充foo.com,试图将数据发送到bar.com。但CORS是   由浏览器强制执行,您所要做的就是将evil.com作为代理   将伪造的原始请求发送到bar.com(数据从Y转到   evil.com,evil.com将其假源设置为foo.com,然后将其发送给   bar.com)。

evil.com已经可以联系bar.com了 - 就像任何使用浏览器的人一样(或卷曲或wget等)。问题是,evil.com强制您的浏览器连接到bar.com,它可能有IP过滤器,cookie,防火墙等保护它,但javascript可以连接到使用您的浏览器。所以浏览器是保护用户的东西。禁止跨域脚本。但有时它是有用的(例如:谷歌apis,或连接到账单支付服务的银行等)跨域脚本。 CORS告诉浏览器在这种情况下它没问题。

不能说没有漏洞,或者标准是最好的,或者浏览器中没有实施漏洞,或者网站过于宽松。但那些是不同的问题......