CORS是执行跨域AJAX请求的安全方法吗?


81

在阅读了CORS(跨源资源共享)后,我不了解它如何提高安全性。如果发送了正确的ORIGIN标头,则允许跨域AJAX通信。例如,如果我发送

来源:http//example.com

服务器检查此域是否在白名单中,以及是否在标头中:

访问控制允许来源:[此处接收的网址]

与响应一起发送回去(这是简单的情况,也有预先要求的请求,但问题是相同的)。

这真的安全吗?如果有人想接收该信息,则伪造ORIGIN标头似乎是一件微不足道的任务。该标准还说该策略在浏览器中执行,如果Access-Control-Allow-Origin不正确,则会阻止响应。显然,如果有人试图获取该信息,他将不会使用标准的浏览器来阻止它。


阅读此答案是因为有人不清楚同源政策和CORS是什么,以及为什么存在它们:stackoverflow.com/a/27294846/3340994
nishantbhardwaj2002

Answers:


52

您无法在网络浏览器中使用JavaScript伪造Origin标头。CORS旨在防止这种情况。

在网络浏览器之外,这无关紧要。它并非旨在阻止人们获取可供公众使用的数据。没有公众的参与,您就无法将其公开。

它的设计是为了给定:

  • Alice,提供旨在通过Ajax访问的API的人
  • 鲍勃(Bob),拥有网络浏览器
  • 查理(Charlie),运行自己的网站的第三方

如果Bob访问Charlie的网站,则Charlie无法将JS发送到Bob的浏览器,以便它从Alice的网站获取数据并将其发送给Charlie。

如果Bob在Alice的网站上拥有一个用户帐户,从而允许他执行诸如发表评论,删除数据或查看公众无法获得的数据之类的事情,上述情况就变得更加重要-因为在没有保护的情况下,Charlie的JS可能会告诉Bob的浏览器在Bob的背后进行操作(然后将结果发送给Charlie)。

如果要阻止未经授权的人员查看数据,则需要使用密码,SSL客户端证书或其他一些基于身份的身份验证/授权方式来保护数据。


1
基本上,CORS或跨域资源共享和授权是两个独立的事物。正如首字母缩写所示,它实际上是允许跨源共享。是否允许客户实际执行此操作由您的授权逻辑确定。
reaper_unique

149

目的是防止这种情况-

  • 您访问网站X
  • 网站X的作者编写了一个邪恶的脚本,该脚本会发送到您的浏览器
  • 在您的浏览器上运行的脚本登录到您的银行网站并执行恶意操作,并且由于该脚本正在您的浏览器中运行因此它具有这样做的权限。

想法是,您的银行网站需要某种方式来告诉浏览器,是否应该信任网站X上的脚本来访问银行中的页面。


9
您的回答也很明确,谢谢。我不赞成,因为它需要15个声望。
Gibarian2001

因此,CORS不是在保护网站X上应用程序的完整性,而是在保护表示要信任Web X来对BANK进行API调用的BANK的完整性吗?
luigi7up 2014年

7
@ luigi7up:不,CORS不保护任何东西,实际上,它通过定义SOP异常“削弱”了安全性。在Access-Control-Allow-Origin其起点(在指定的标头指定Origin报头)被允许访问该资源。通常,只有具有相同来源的请求才被允许这样做。这里最重要的部分是:允许/拒绝是由浏览器而不是服务器强制执行的。这意味着Access-Control-Allow-Origin保护您的浏览器,而不是服务器或服务器本身上的资源。
丹尼尔·楼

是什么阻止网站X的作者通过您的网站后端将您登录到银行,然后将该网站用作代理?这只是他必须创建的一个附加层,但它将完全避开他在浏览器中可能遇到的CORS问题。.因此,这似乎是一个仅用于浏览器的保护,如果您可以解决的话,对我来说似乎毫无意义。以一种非常简单的方式..
pootzko

1
@pootzko:在您的情况下,恶意网站X不会为银行网站建立有效会话。即使受害者登录了银行账户(例如,在另一个选项卡中),由于浏览器实施的cookie策略,恶意站点X也无法访问该会话:浏览器永远不会发送该会话的cookie。银行网站X.
丹尼尔·F。

64

仅添加@jcoder的答案,Origin标头的全部目的并不是保护服务器上请求的资源。该任务完全通过其他方式由服务器本身承担,这完全是因为攻击者确实能够使用适当的工具来欺骗此标头。

该点Origin报头是为了保护用户。该方案如下:

  • 攻击者创建恶意网站M

  • 用户Alice被欺骗连接到M,该用户包含一个脚本,该脚本尝试通过实际支持CORS的服务器B上的CORS执行某些操作

  • B的Access-Control-Allow-Origin标题中可能没有M ,为什么会这样呢?

  • 关键点在于,M无法欺骗或覆盖Origin标头,因为请求是由Alice的浏览器发起的。因此,她的浏览器会将(正确)设置Origin为M,而不是Access-Control-Allow-OriginB的M ,因此请求将失败。

爱丽丝可以Origin自己更改标题,但是为什么要这么做,因为这意味着她在伤害自己?

TL; DR:Origin标头保护无辜的用户。它不保护服务器上的资源。攻击者可以在自己的计算机上进行欺骗,但不能在不受其控制的计算机上进行欺骗。

服务器仍应保护其资源,因为匹配的Origin标头并不意味着授权的访问。但是,Origin不匹配的标头表示未经授权的访问。


11
很好的答案。最好的整体恕我直言。
petersaints's

为什么这不是所选答案?这显然是最好的。这个答案中提到的第四点是发帖人的真正要求。
alaboudi

最佳答案丹尼尔。这就是CORS的全部要点:“关键点在于,M无法欺骗或覆盖Origin标头,导致请求是由ALICE的浏览器发起的。因此,她的浏览器会将(正确的)Origin设置为M,不在B的Access-Control-Allow-Origin中,因此请求将失败。”
卢卡斯·卢卡奇

14

相同来源政策的目的并不是阻止人们普遍访问网站内容;如果有人想这样做,他们甚至不需要浏览器。关键是要停止客户端脚本在没有必要访问权限的情况下访问另一个域上的内容。参见Wikipedia条目中的同源起源策略


2
“目的是阻止客户端脚本访问另一个域上的内容”,这是通过Same Origin Policy解决的。没有?我的意思是我的网站向您发送了一些JS,并且您的浏览器不允许对其他域的Ajax调用。这是相同的原产地政策。CORS做的很对立-允许我的Ajax访问其他域。我在这里错过了一些
大事

to @ luigi7up:是的,CORS相反。它使网站的所有者可以从多个受信任的域中授予对其服务的访问权限。
SergeyT

6

阅读有关CORS的内容后,我不了解它如何提高安全性。

CORS不能提高安全性。CORS为服务器提供了一种机制,以告知浏览器外部域应如何访问它们,并且它试图以与CORS之前存在的浏览器安全模型(即,相同起源策略)一致的方式进行访问。

但是,同源起源策略和CORS的范围有限。具体来说,CORS规范本身没有拒绝请求的机制。它可以使用标头来告诉浏览器不要让来自外部域的页面读取响应。并且,对于预检请求,它可以要求浏览器不要向外部域发送某些请求。但是,CORS没有指定服务器拒绝(即不执行)实际请求的任何方式。

让我们举个例子。用户A通过cookie登录到站点。用户加载恶意网站M,它试图提交,做了一个表格POSTA。会发生什么?好吧,无论是否具有CORS,以及M是否具有允许的域,浏览器都将A使用用户的授权cookie将请求发送到,服务器将执行恶意程序POST,就像用户发起了该恶意程序一样。

这种攻击称为“跨站请求伪造”,而CORS本身并没有采取任何措施来缓解它。因此,如果您允许请求代表用户更改数据,那么CSRF保护如此重要。

现在,Origin标头的使用可能是CSRF保护的重要组成部分。实际上,对其进行检查是当前针对多管CSRF防御的建议的一部分。但是Origin头的使用不在CORS规范范围内。

总而言之,CORS是将现有的“相同来源策略”安全模型扩展到其他接受域的有用规范。它不会增加安全性,并且站点需要与CORS之前相同的防御机制。


1

我来晚了,但我认为这里没有任何帖子可以真正提供所需的答案。最大的收获应该是浏览器是正在编写origin标头值的代理。恶意脚本无法写入origin标头值。当服务器回复Access-Control-Allow-Origin标头时,浏览器将尝试确保此标头包含origin之前发送的值。如果不是,它将触发错误,并且不会将值返回给请求的脚本。当您想拒绝对恶意脚本的回答时,此问题的其他答案为您提供了一个很好的方案。

@daniel f也为问题提供了一个很好的答案

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.