如何阻止恶意代码欺骗“origin”;头利用CORS?

我理解的方式是,如果一个客户端脚本运行在foo.com的页面上,想要从bar.com请求数据,在请求中它必须指定标头Origin: http://foo.com,而bar必须用Access-Control-Allow-Origin: http://foo.com响应。

有什么阻止恶意代码从站点roh.com简单欺骗头Origin: http://foo.com从酒吧请求页面?

56284 次浏览

浏览器可以控制Origin标头的设置,用户不能覆盖这个值。所以你不会看到浏览器欺骗Origin标头。恶意用户可以创建一个curl请求,手动设置Origin报头,但此请求将来自浏览器外部,并且可能没有浏览器特定的信息(例如cookie)。

记住:CORS不是证券。不要依赖CORS来保护您的站点。如果您正在提供受保护的数据,请使用cookie或OAuth令牌或Origin标头以外的其他东西来保护数据。CORS中的Access-Control-Allow-Origin头只规定了应该允许哪些源进行跨源请求。别再依赖它了。

没有什么可以阻止恶意代码欺骗源。当这种情况发生时,您的服务器将永远不会知道它,并将对请求采取行动。有时这些请求是昂贵的。所以不要用CORS来代替任何类型的证券。


我最近一直在研究CORS,我也问过自己同样的问题。我发现浏览器可能足够聪明,当它看到一个欺骗的CORS请求时就能知道,但您的服务器没有那么聪明。

我发现的第一件事是Origin报头是一个HTTP 禁止使用的头名称,不能通过编程修改。这意味着你可以在大约8秒内使用修改谷歌Chrome头修改它。

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

然后我欺骗客户端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,并正确地拒绝响应。现在哪个不重要了,因为服务器已经接受了欺骗的请求,花了我的钱。

简单总结一下:

问:同源策略(SOP)仅由浏览器强制执行?
< / >强是的。对于在浏览器内进行的所有调用,该SOP肯定是由浏览器应用的。服务器可能检查请求的来源,也可能不检查。

问:如果请求不符合SOP,浏览器会阻止它吗?
答:不,超出浏览器权限。浏览器只是发送跨源请求,并等待响应,以查看服务器通过Access-Control-*报头是否表示调用合法。如果服务器没有返回Access-Control-Allow-Origin头,没有回显调用者的源,或者没有在头中返回*,那么浏览器所要做的就是避免向调用者提供响应。

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

所以如果我可以通过改变Origin来欺骗服务器,这是否意味着CORS是不安全的?
答: CORS本身对安全性保持沉默——即请求的身份验证和授权。由服务器来检查请求,并通过它们使用的任何机制(如cookie和报头)对其进行身份验证/授权。话虽如此,在遇到XSS这样的攻击时,它可以保护我们更多:

< >强的例子: 假设你已经登录到你的网站,一个恶意脚本试图向你的银行网站发送一个请求,以查询你的余额:反映XSS攻击。您的银行网站信任来自(这里代表)您的网站的凭据,因此请求得到验证,并发出针对恶意代码的HTTP响应。如果你的银行网站不关心与其他来源共享它的端点,它不会在响应中包含Access-Control-Allow-Origin报头。 现在,在请求到达时,浏览器意识到该请求是一个Cross Origins请求,但响应并没有显示服务器愿意与您的网站共享资源(这里是平衡查询端点)。因此它破坏了流,因此返回的结果永远不会到达恶意代码

这个话题有点老了,但肯定有帮助,我将为那些想知道是否有办法防止攻击者欺骗cors的人添加以下提示。

如上所述,没有办法防止Origin头被欺骗。

然而,如果你正在构建一个API,返回公开显示的数据,并希望避免攻击者溢出服务器来检索所有数据,你可以执行以下操作:

  • 防止全局数据请求(一次返回所有可用数据的查询)
  • 设置一个记录器,检查恶意用户是否正在编辑或创建脚本以发送多个快速后续请求。您可以使用IP地址和其他唯一头的组合来尝试实现这一点。

如果您想保护一个rest API, HMAC或Oauth2是最好的选择(每个都有自己的目的)。

但是cors始终是可编辑的,永远不应该用来检查请求发送者的身份。