跨域资源共享(CORS)的工作原理引起了混淆

6
据我理解,关于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不会将数据发送给它。
我感觉我没有真正理解重要的事情。非常感谢你的帮助。

我也有同样的想法 - 每个关于CORS的解释都应该有一个免责声明,提到它如何通过代理被规避。我不确定如何轻松地检测这种攻击。希望你像TJ说的那样注意并关心,但我想在大多数情况下,它很容易被忽视。 - Rene Wooller
2个回答

5
然而,这对我来说真的没有意义。我认为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可以做什么。

bar.com会如何知道呢?这是因为你的代理每次都会有相同的IP地址吗?如果你的网站遭受了跨站脚本攻击(XSS)(http://en.wikipedia.org/wiki/Cross-site_scripting),那么让foo.com强制执行foo.com所能做的事情确实是有意义的,但我想CORS并没有试图阻止这种攻击。 - user1830568
@user1830568:由于IP或IP范围,由于请求的确切内容等原因。关于XSS,防止这些攻击是foo.com的职责,需要编写防御性代码。 - T.J. Crowder

3
这不是关于Foo.com或Bar.com,而是关于用户。
CORS有两个作用。第一个是保护防火墙后面的资源。第二个是保护通常受保护的资源,除非从带有身份验证或其他敏感数据cookie的浏览器发送请求。
CORS是一种浏览器技术,并得到服务器支持,允许foo有限地调用其域外部的内容。它是针对跨域脚本的限制开了一个小口子。
任何人都可以伪造ORIGIN标头并创建CORS预检或简单请求-当然,任何人都可以直接连接到Bar服务器,并且完全不使用CORS进行请求。任何浏览器都可以直接连接到bar.com并获取数据。但是现代浏览器不会运行来自foo.com的脚本以访问bar.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-就像任何使用浏览器的人一样(或curl或wget等)。问题是evil.com是否可以强制您的浏览器连接到可能具有IP过滤器、cookie、防火墙等保护的bar.com,但javascript可以使用您的浏览器连接到它。因此,浏览器是保护用户的东西。通过禁止跨域脚本。但是有时跨域脚本很有用(例如:Google API或银行连接到账单支付服务等)。CORS告诉浏览器在这种情况下是可以的。

这并不意味着没有漏洞,或者说标准是最好的,或者浏览器实现中没有漏洞,或者网站太宽容。但这些都是不同的问题...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接