原文:https://portswigger.net/blog/exploiting-cors-misconfigurations-for-bitcoins-and-bounties

本文内容摘自我在AppSec USA大会上发表的演讲,准确来说,这里已经做了极大的简化。如果您有时间(或在阅读本文是遇到难以理解的内容)的话,我强烈建议您查看相应的幻灯片视频

跨源资源共享(CORS)是一种放宽同源策略要求的机制,以使不同的网站可以通过浏览器进行通信。通常来说,人们普遍认为某些CORS配置是非常危险的,但具体到这些配置的细微差别及其含义,却很少有人能够正确理解。在这篇文章中,我将为读者展示如何从黑客的角度来批判性地检查CORS配置的漏洞,并利用它们来窃取比特币。

黑客之于CORS


网站可以通过发送以下HTTP响应头部来启用CORS:

Access-Control-Allow-Origin: https://example.com

这样的话,就允许访问指定的源(域,这里为“https://example.com”)的浏览器向该网站发送跨域请求并读取响应——对于[同源策略](https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy "同源策略")来说,通常是不允许的。在默认情况下,发送跨域请求时不会携带cookie或其他凭据,因此,它不能用于窃取与用户相关的敏感信息(如CSRF令牌)。不过,网站服务器也可以使用以下头部来启用凭据传输:

Access-Control-Allow-Credentials:true

这样就能建立起信任关系:如果example.com上存在XSS漏洞的话,对该网站来说,可能会带来巨大的危害。

大隐隐于市


如您所见,实现对单个域的信任是非常容易的事情。不过,如果需要信任多个域的话,那该怎么办呢?根据相关规范的建议,只需列出相关的域,并用空格加以分隔即可,例如:

Access-Control-Allow-Origin:http://foo.com http://bar.net


但是,没有哪个浏览器真正支持这一特性。

当然,读者可能还希望使用通配符来信任所有子域,具体方法是:

Access-Control-Allow-Origin: *.portswigger.net
But that won't work either. The only wildcard origin is '*'

实际上,CORS自身也提供了一个隐蔽的安全措施。如果您想完全禁用SOP,并通过下面的头部组合将自己的网站暴露给所有人:

Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true

这时,将在浏览器控制台中收到以下错误消息:

“当凭证标志为true时,无法在Access-Control-Allow-Origin中使用通配符。”

规范中提到了这个异常,并且Mozilla的文档也提供了相应的说明

“在响应凭证请求时,服务器必须指定域,并且不能使用通配符”

换句话说,使用通配符可以有效地禁用Allow-Credentials头部。

由于存在这些限制,所以,许多服务器都是以编程的方式根据用户提供的Origin头部值来生成“Access-Control-Allow-Origin”头部的。如果您发现了带有“Access-Control- *”头部却未声明相关域的HTTP响应的话,则强烈表明,该服务器是根据您的输入来生成头部的。而其他服务器只有收到包含Origin头部的请求后,才会发送CORS头部,这使得相关的漏洞非常容易被遗漏。

凭证与比特币


点击收藏 | 1 关注 | 1
  • 动动手指,沙发就是你的了!
登录 后跟帖