据我了解,如果在foo.com页面上运行的客户端脚本想要从bar.com请求数据,则在请求中必须指定标头Origin: http://foo.com
,而bar必须以响应Access-Control-Allow-Origin: http://foo.com
。
有什么方法可以阻止roh.com网站上的恶意代码简单地欺骗标头Origin: http://foo.com
从bar请求页面?
据我了解,如果在foo.com页面上运行的客户端脚本想要从bar.com请求数据,则在请求中必须指定标头Origin: http://foo.com
,而bar必须以响应Access-Control-Allow-Origin: http://foo.com
。
有什么方法可以阻止roh.com网站上的恶意代码简单地欺骗标头Origin: http://foo.com
从bar请求页面?
Answers:
浏览器可以控制Origin
标题的设置,用户无法覆盖此值。因此,您不会看到Origin
来自浏览器的标头。恶意用户可以制作手动设置Origin
标头的curl请求,但是该请求将来自浏览器外部,并且可能没有特定于浏览器的信息(例如cookie)。
请记住:CORS不是安全的。不要依靠CORS保护您的网站。如果您要提供受保护的数据,请使用Cookie或OAuth令牌或Origin
标头以外的其他内容来保护该数据。Access-Control-Allow-Origin
CORS中的标头仅指示应允许哪个起源发出跨域请求。不要再依赖它了。
TLDR:没有什么能阻止恶意代码欺骗来源。发生这种情况时,您的服务器将永远不知道它,并将根据请求采取行动。有时,这些请求很昂贵。因此,请勿使用CORS代替任何类型的安全性。
我最近一直在和CORS玩耍,我也问过自己同样的问题。我发现,浏览器可能足够聪明,可以在看到欺骗性的CORS请求时知道它,但是您的服务器却不那么聪明。
我发现的第一件事是Origin
标头是HTTP 禁止的标头名称,无法以编程方式进行修改。这意味着您可以使用Google Chrome的“修改标题”在大约8秒钟内对其进行修改。
为了测试这一点,我设置了两个客户端域和一个服务器域。我在服务器上添加了一个CORS白名单,该白名单允许来自客户端1的CORS请求,但不允许来自客户端2的CORS请求。我测试了两个客户端,确实客户端1的CORS请求成功,而客户端2的失败。
然后,我欺骗了客户端2的Origin
标头以匹配客户端1的标头。服务器接收到欺骗性的Origin
标头,并成功通过了白名单检查(如果您是半杯半空的家伙,则失败)。此后,服务器通过消耗其计划使用的所有资源(数据库调用,发送昂贵的电子邮件,发送甚至更昂贵的sms消息等)来尽职地执行任务。完成后,服务器会愉快地将欺骗的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
并正确拒绝了响应。这无关紧要,因为服务器已经接受了欺骗的请求并花了我的钱。
There's nothing stopping malicious code from spoofing the origin
->是的,javascript无法设置Origin
。是的,用户可以修改其浏览器/使用提琴手来更改原点,但这并不是CORS的防御目标。攻击者控制的网站无法更改Origin,这很重要。
总结一下:
问:相同来源策略(SOP)仅由浏览器执行吗?
答:是的。对于您在浏览器中进行的所有呼叫,SOP肯定是由浏览器应用的。服务器可能会或可能不会检查请求的来源。
问:如果请求不符合SOP,浏览器是否会阻止它?
答:不,这超出了浏览器的权限。浏览器只是发送跨源请求,然后等待响应,以查看服务器是否通过Access-Control
-*标头将呼叫合法地发出信号。如果服务器不发送回Access-Control-Allow-Origin
标头,不回显调用方的来源或不发送回*
标头,则浏览器要做的所有事情就是避免向调用方提供响应。
问:这是否意味着我不能欺骗Origin
?
答:在浏览器中并使用脚本,您无法覆盖Origin
它,因为它处于浏览器的控制之下。但是,如果您想入侵自己,则可以使用安装在计算机上的浏览器扩展或其他工具来篡改从浏览器发出的呼叫。您也可以发出HTTP
使用电话curl
,Python
,C#
等,并改变Origin
头欺骗服务器。
问:因此,如果我可以通过更改来欺骗服务器Origin
,这CORS
是否不安全?
答: CORS
本身对安全性保持沉默-即请求的身份验证和授权。服务器可以根据请求使用的任何机制(例如Cookie和标头)来检查请求并进行身份验证/授权,这取决于服务器。话虽如此,它可以在发生XSS之类的攻击时为我们提供更多保护:
示例:
假设您已经登录到网站,并且恶意脚本试图向银行网站发送请求以查询余额:Reflected XSS攻击。您的银行网站信任来自(代表此处)网站的凭据,因此请求得到身份验证,并发出HTTP
针对恶意代码的响应。如果您的银行网站不关心与其他来源共享其端点,则不包括Access-Control-Allow-Origin
响应中的标头。现在,在请求到达时,浏览器意识到该请求是Cross Origins请求,但是响应并不表明服务器愿意与您的网站共享资源(此处为余额查询端点)。因此,它破坏了流程,因此返回的结果将永远不会到达恶意代码。
foo.com
)必须提供Access-Control-Allow-Origin
标头,否则浏览器不允许该请求bar.com
。