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

时间:2014-01-11 03:25:56

标签: 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的页面?

4 个答案:

答案 0 :(得分:109)

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

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

答案 1 :(得分:26)

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

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

我发现的第一件事是Origin标头是HTTP forbidden header name,无法以编程方式修改。这意味着您可以使用Modify Headers for Google Chrome在约8秒内修改它。

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

然后我欺骗客户端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并正确拒绝响应。 此时无关紧要因为服务器已经接受了欺骗请求并花了我的钱。

答案 2 :(得分:2)

简而言之:

问:是否仅由浏览器执行同一个原产地政策(SOP)?
A:是。对于您在浏览器内进行的所有呼叫,SOP肯定由浏览器应用。服务器可能会或可能不会检查请求的来源。

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

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

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

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

答案 3 :(得分:1)

这个话题有点老,但绝对有用,我将添加以下提示,供任何想知道是否有任何方法可以防止攻击者欺骗 cors 的人使用。

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

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

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

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

但 cors 将始终保持可编辑状态,不应用于检查请求发射器的身份。