如何阻止恶意代码欺骗“Origin”标头以利用 CORS?

2022-08-30 01:24:16

我的理解是,如果在 foo.com 页面上运行的客户端脚本想要从 bar.com 请求数据,则在请求中它必须指定标头 ,并且bar必须以.Origin: http://foo.comAccess-Control-Allow-Origin: http://foo.com

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


答案 1

浏览器可以控制标头的设置,用户无法覆盖此值。因此,您不会看到来自浏览器的标头被欺骗。恶意用户可以手工创建手动设置标头的 curl 请求,但此请求将来自浏览器外部,并且可能没有特定于浏览器的信息(如 Cookie)。OriginOriginOrigin

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


答案 2

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


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

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

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

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

我读过的文档指出,收到的值必须与请求中发送的值完全匹配。它们确实匹配,因此当我在Chrome中看到以下消息时,我感到很惊讶:Access-Control-Allow-OriginOrigin

XMLHttpRequest 无法加载 。“访问控制-允许-源”标头的值不等于提供的源。因此,不允许访问源。http://server.dev/testhttp://client1.devhttp://client2.dev

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