当前位置: 首页 > 知识库问答 >
问题:

如何阻止恶意代码欺骗“起源”头来利用CORS?

皇甫礼骞
2023-03-14

按照我的理解,如果客户端脚本在来自foo的页面上运行。com希望从bar请求数据。com,在请求中必须指定头来源:http://foo.com,bar必须响应访问控制允许原点:http://foo.com

有什么可以阻止来自roh网站的恶意代码。com从简单的欺骗头来源:http://foo.com是否从工具栏请求页面?

共有3个答案

万俟鸿波
2023-03-14

简单总结一下:

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

问:如果请求不符合SOP,浏览器是否会阻止它<不,这超出了浏览器的权限。浏览器只发送跨源请求并等待响应,以查看服务器是否通过访问控制-*标题发出合法呼叫信号。如果服务器不发回Access Control Allow Origin标题,不回显调用者的来源,或者在标题中不发回*,那么浏览器所做的就是避免向调用者提供响应。

问:这是否意味着我不能欺骗源代码
A:在浏览器中并使用脚本,您不能覆盖Origin,因为它在浏览器的控制下。但是,如果你想攻击自己,你可以使用浏览器扩展或你机器上安装的其他工具来篡改从你的浏览器发出的呼叫。您还可以使用curlPythonC#等发出HTTP调用,并更改Origin头来欺骗服务器。

问:所以,若我可以通过改变源代码来欺骗服务器,这是否意味着CORS不安全
A:CORS本身不涉及安全性,即请求的身份验证和授权。由服务器来检查请求,并通过它们使用的任何机制(如cookie和标头)对请求进行身份验证/授权。话虽如此,它可以在发生XSS之类的攻击时为我们提供更多的保护:

示例:假设您已登录到您的网站,一个恶意脚本试图向您的银行网站发送请求以查询您的余额:一个反射的XSS攻击。您的银行网站信任来自(此处代表)您网站的凭据,因此请求将得到验证,并发出针对恶意代码的HTTP响应。如果您的银行网站不关心与其他来源共享其endpoint,则不会在响应中包含访问控制允许来源标题。现在,当请求到达时,浏览器意识到该请求是一个跨来源请求,但响应并不表示服务器愿意与您的网站共享资源(这里是平衡查询endpoint)。因此它破坏了流,因此返回的结果永远不会到达恶意代码。

丁经国
2023-03-14

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

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

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

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

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

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

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

我读的文档似乎不准确。Chrome的网络标签清楚地显示了请求和响应头,如http://client1.dev,但您可以在错误中看到,Chrome不知何故知道真正的来源是http://client2.dev并正确拒绝响应。这一点无关紧要,因为服务器已经接受了伪造的请求并花掉了我的钱。

应涵容
2023-03-14

浏览器可以控制Origin标头的设置,用户不能覆盖该值。因此,您不会看到浏览器中伪造的Origin标头。恶意用户可以手工创建手动设置Origin标头的curl请求,但此请求来自浏览器外部,并且可能没有特定于浏览器的信息(如cookie)。

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

 类似资料:
  • 问题内容: 据我了解,如果在foo.com页面上运行的客户端脚本想要从bar.com请求数据,则在请求中必须指定标头,而bar必须以响应。 有什么方法可以阻止roh.com网站上的恶意代码简单地欺骗标头从bar请求页面? 问题答案: 浏览器可以控制标题的设置,用户无法覆盖此值。因此,您不会看到来自浏览器的标头。恶意用户可以制作一个手动设置标头的curl请求,但是该请求将来自浏览器外部,并且可能没有

  • 我有一个PHP应用程序,我们正在添加测试,使用代码欺骗。我们试图添加指定(和验证)到我们的套件,但它不被识别。你如何正确设置指定与代码欺骗一起使用? 在我的composer.json中,我有以下内容: 我在添加指定和验证后运行了作曲家更新,并获得了以下输出: 我有一个这样的测试(主要是由generate:test生成的): 当我运行单元测试时,我会得到以下输出: 我使用的参考文献是:http://

  • 我正在编写一组简单的PHP函数,我只使用纯PHP7,没有框架,什么都没有。这些函数稍后将在CMS中的插件中使用,但这不是重点。我想使用Codeception为我的函数编写单元测试(为了熟悉它,我知道Codeception基本上只在这里运行PHPUnit),但我真的不知道如何以合理的方式将Codeception指向我的代码。 我的结构如下:我有,其中包含我想要测试的函数,大致如下: 我使用Compo

  • 我已经按照他们网站上的指南安装了Codeception。创建第一个测试。 $I=新WebGuy($scenario); $I- $I- $I- 当我们开始测试php codecept.phar运行时,我们得到了什么: Codeception PHP测试框架v1.6.5由Sebastian Bergmann的PHPUnit 3.7.23提供支持。PHP注意:在第163行的phar://C:/wamp

  • 我试图在每个测试套件开始时进行一个API调用,但没有找到这样做的方法。在我的模块中,我重载了方法,但是当我试图从REST模块调用时,我得到了错误。我的模块类看起来像这样: 这给了我一个PHP错误: 对/../vendor/codeception/codeception/src/codeception/Module/REST.php:476中的非对象调用成员函数request() 我如何在\u be

  • 当我在验收测试中更改应用程序模型时,测试实际使用该模型,当我在功能测试中更改应用程序模型时。。。测试仍然使用yii/web/application,我需要它来使用我的公共/组件/应用程序模型。我怎样才能改变这一点? 功能_bootstrap包含我的自定义模型...(通用/组件/应用程序)我完全困惑...... 当我运行测试代码时: 然后我得到错误: 这个nowSQL是在common\compone