什么是阻止恶意代码欺骗"Origin"标头来利用CORS?

Jay*_*ont 112 javascript ajax http cors

我理解它的方式,如果在foo.com页面上运行的客户端脚本想要从bar.com请求数据,请求必须指定标题Origin: http://foo.com,并且栏必须响应Access-Control-Allow-Origin: http://foo.com.

有什么可以阻止来自网站roh.com的恶意代码简单地欺骗标题Origin: http://foo.com来请求来自bar的页面?

mon*_*sur 129

浏览器可以控制设置Origin标头,用户无法覆盖此值.所以你不会看到Origin浏览器欺骗的标题.恶意用户可以制作手动设置Origin标头的卷曲请求,但此请求将来自浏览器外部,并且可能没有特定于浏览器的信息(例如cookie).

请记住:CORS不是安全性.不要依赖CORS来保护您的网站.如果您要提供受保护的数据,请使用Cookie或OAuth令牌或Origin标头以外的其他内容来保护该数据.Access-Control-Allow-OriginCORS中的标题仅指示应允许哪些来源进行跨源请求.不要再依赖它了.

  • 如果有人想要欺骗某些东西,那么他们就可以这样做.使用几乎任何脚本语言,他们可以构建http请求.Perl和Python有http库,这使得这很容易.库存储和发送cookie,允许您添加任意标头,并提供大量的调试信息.因此,当您在浏览器中登录时,CORS标题只会使您在阅读的论坛上更难以对您在其他域上的银行帐户执行令人讨厌的操作. (35认同)
  • "浏览器可以控制设置Origin标头,用户无法覆盖此值." 我确信在请求离开浏览器后,使用像Fiddler2或Charles这样的工具来修改标题非常容易. (10认同)
  • 只是为了澄清,恶意用户可以简单地生成一个已修补的浏览器实例,允许他们手动控制Origin标头,然后完全冒充普通用户,cookie,AJAX等等. (8认同)
  • *恶意用户可以简单地生成一个已修补的浏览器实例,以允许他们手动控制Origin标头*如果您可以访问该计算机,直到您可以"简单地生成修补的浏览器实例"(实际上并不发声)这对我来说很简单),为什么不直接从磁盘读取cookie?它们以您知道的纯文本存储.在现实生活中,跨站点脚本是一个真正的威胁,而你的攻击场景只是设计和不切实际. (3认同)
  • 这很有道理.如果浏览器不允许JavaScript覆盖Origin标头,则没有问题.如果您正在从浏览器外部执行请求,那么您将不会拥有cookie.我想我很困惑,因为在我阅读的所有文档中,没有任何地方明确说明Origin头*不能被覆盖.谢谢! (2认同)

Noc*_*rno 29

TLDR:没有什么能阻止恶意代码欺骗原点.当发生这种情况时,您的服务器将永远不会知道它并将根据请求采取行动.有时这些请求很昂贵.所以不要使用CORS代替任何类型的安全性.


我最近一直在玩CORS,我问自己同样的问题.我发现浏览器可能足够智能,当它看到一个时,它就知道一个欺骗性的CORS请求,但是你的服务器并不那么聪明.

我发现的第一件事是Origin标题是HTTP 禁止的标题名称,无法以编程方式进行修改.这意味着您可以使用Google Chrome的修改标题在大约8秒内修改它.

为了测试这一点,我设置了两个客户端域和一个服务器域.我在服务器上包含了一个CORS白名单,它允许来自客户端1但不来自客户端2的CORS请求.我测试了两个客户端,实际上客户端1的CORS请求在客户端2失败时成功.

然后我欺骗Client 2的Origin标题以匹配客户端1.服务器收到了欺骗性Origin标题,并成功通过了白名单检查(如果你是一个半空的人,那就失败了).之后,服务器通过消耗它设计使用的所有资源(数据库调用,发送昂贵的电子邮件,发送更昂贵的短信等)来尽职尽责地执行.完成后,服务器愉快地将欺骗的Access-Control-Allow-Origin标头发送回浏览器.

我读过的文档说明Access-Control-Allow-Origin收到的值必须与Origin请求中发送的值完全匹配.他们匹配,所以当我在Chrome中看到以下消息时,我感到很惊讶:

XMLHttpRequest无法加载http://server.dev/test.'Access-Control-Allow-Origin'标头的值http://client1.dev 不等于提供的原点.http://client2.dev 因此不允许原点访问.

我读过的文件似乎不准确.Chrome的网络标签清楚地显示了请求和响应标题http://client1.dev,但您可以在错误中看到Chrome以某种方式知道真实来源http://client2.dev并正确拒绝响应.此时无关紧要,因为服务器已经接受了欺骗请求并花了我的钱.

  • 根本不是很棒.它完全错过了CORS的观点.如果您能够拦截来自用户计算机的请求,您只需阅读其Cookie,安装键盘记录程序,病毒以及所有其他真正的威胁即可.CORS用于保护从恶意脚本登录到站点A的诚实用户,该恶意脚本以某种方式注入站点B.站点B上的脚本(可能是论坛帖子中的Javascript片段未被站点B正确转义)执行用户帐户下的网站A上的操作(例如删除内容等),使用来自网站A的会话cookie. (9认同)
  • 这称为跨站点脚本,无需CORS即可完成,无需控制用户的计算机.这就是重点.无法控制用户的计算机,因为在向站点A发出请求时,浏览器用于自动将会话cookie添加到请求中,因此它看起来像是来自用户本身的有效请求,而实际上它来自其他一些脚本现场.Same-Origin策略阻止它,并且CORS用于将应该被授予访问权限的域列入白名单,即使它们位于不同的源上. (3认同)
  • @Nocturno是的,我可能有点太粗暴,抱歉.你原来的立场.Same-Origin策略是一种浏览器安全功能,CORS是一种通过将某些域列入白名单来削弱该安全性的机制.OP需要明白,欺骗Origin头部并不是真正可行的"攻击",因为它不会带给你任何不能用例如curl的东西. (3认同)
  • @Nocturno,谢谢你的例子.让我加上我的观察.CORS涉及浏览器安全功能.如果安全浏览器从其原始状态进行修改,则可能会被解释为浏览器可能缺少安全功能. (2认同)
  • @StijndeWitt 实际上,我的目的是通过表明没有什么可以阻止恶意代码欺骗源头来回答最初的问题。当这种情况发生时,你的服务器永远不会知道它,并将请求的响应发送回它,有时这些请求/响应是昂贵的。因此,请勿使用 CORS 代替任何类型的安全性。 (2认同)
  • @Nocturno我认为您的开幕词有点误导。`没有阻止恶意代码欺骗来源的方法->是的,JavaScript无法设置`Origin`。是的,用户可以修改其浏览器/使用提琴手来更改原点,但这并不是CORS的防御目标。_攻击者控制的网站_不能更改Origin,这很重要。 (2认同)

Ali*_*eza 5

总结一下:

问:相同来源策略(SOP)仅由浏览器执行吗?
答:可以。对于您在浏览器内进行的所有呼叫,SOP肯定由浏览器应用。服务器可能会或可能不会检查请求的来源。

问:如果请求不符合SOP,浏览器是否会阻止它?
答:不,这超出了浏览器的权限。浏览器只是发送跨源请求,然后等待响应,以查看服务器是否通过Access-Control-*标头将呼叫合法地发出信号。如果服务器不发送回Access-Control-Allow-Origin标头,不回显调用方的来源或不发送回*标头,则浏览器要做的所有事情就是避免向调用方提供响应。

问:这是否意味着我不能欺骗Origin
答:在浏览器中并使用脚本,您无法覆盖Origin它,因为它在浏览器的控制之下。但是,如果您想入侵自己,则可以使用安装在计算机上的浏览器扩展或其他工具来篡改从浏览器发出的呼叫。您也可以发出HTTP使用电话curlPythonC#等,并改变Origin头欺骗服务器。

问:因此,如果我可以通过更改来欺骗服务器Origin,这CORS是否不安全?
答: CORS每句话都没有提及安全性-即请求的身份验证和授权。服务器可以根据请求使用的任何机制(例如Cookie和标头)来检查请求并进行身份验证/授权,这取决于服务器。话虽如此,它在发生XSS之类的攻击时可以为我们提供更多保护:

示例: 假设您已经登录到网站,并且恶意脚本试图向银行网站发送请求以查询余额:Reflected XSS攻击。您的银行网站信任来自(代表)您网站的凭据,因此请求可以通过身份验证,并发出HTTP针对恶意代码的响应。如果您的银行网站不关心与其他来源共享其端点,则不包括Access-Control-Allow-Origin响应中的标头。现在,在请求到达时,浏览器意识到该请求是Cross Origins请求,但是响应并不表明服务器很乐意与您的网站共享资源(此处是余额查询端点)。因此,它破坏了流程,因此返回的结果将永远不会到达恶意代码。