CORS漏洞学习

CORS漏洞学习

Whoisa 黑客白帽子 2024-08-31 10:42

感谢师傅 · 关注我们

由于,微信公众号推送机制改变,现在需要设置为星标才能收到推送消息。大家就动动发财小手设置一下呗!啾咪~~~

CORS漏洞

CORS(Cross-Origin Resource Sharing)是一种用于Web应用程序的安全机制,用于控制在浏览器中一个网页能够访问来自另一个源(域名、协议或端口)的资源。CORS漏洞指的是在CORS机制实现上存在的安全问题。
1. 简介

CORS漏洞指的是当一个网站未正确配置CORS策略时可能会导致的安全问题。如果服务器未正确配置CORS规则,攻击者可以通过在恶意网站上的JavaScript代码,利用用户在浏览器中登录受害网站的凭据,从而发送跨域请求到受害网站并获取敏感信息。这种漏洞可能会导致信息泄露等安全问题。

下面用AB两个网站举例,A网站表示正常网站,B网站是攻击者的网站。

A网站有个接口,是返回用户个人信息的。先判断用户是否登录,如果登录那么就会返回登录信息,如果没有登录则返回未登录的消息。

登录代码如下:

如果登录成功,那么访问getinfo会得到一个json数据,登录失败则是提示重新登录。

登录成功如下:


未登录情况如下:


那么假设我们在a网站登录成功的状态下,这时候访问getinfo接口的时候返回了身份信息。那么这时候又去访问b网站。b网站是一个恶意网站,b网站的js会发送一个请求,请求的是a网站的getinfo接口。b网站的代码如下:

很简单就是一个img标签,通过src属性对getinfo接口发送请求,那么这时候是不是会附带a网站的cookie过去,然后就可以劫持a网站的用户信息。示意图下:

步骤1:登录A网站

步骤2:打开B网站

也没有返回信息。

可以发现其实是不能劫持a网站用户信息的。这是由于浏览器同源策略做了限制。实际上也就是浏览器不会把cookie携带过去。

同源策略(Same-Origin Policy)是一种浏览器安全机制,用于限制不同源之间的交互,以防止恶意网站通过跨域请求获取用户的敏感信息或进行其他攻击。

同源指的是协议(Protocol)、域名(Domain)和端口(Port)相同。如果两个页面的协议、域名和端口都相同,则它们被认为是同源的,可以自由地进行数据交互。而如果其中任意一项不相同,就被视为跨域请求。

同源策略限制了以下行为:
1. Cookie、LocalStorage 和 IndexDB 等存储的读取:跨域请求无法访问目标网站的存储信息。

  1. DOM 的访问限制:跨域请求无法获取目标网站的 DOM 元素。

  2. AJAX 请求限制:跨域请求无法直接发送 AJAX 请求。

然而,同源策略也允许一些特定的跨域行为:
1. 跨域资源共享(CORS):服务器可以通过设置响应头来允许特定的跨域请求。

  1. JSONP:利用script标签的跨域特性,通过动态插入

在真实场景下比如多了一个子域名pay.a.com,这个子域名需要获取到a.com/getinfo.php这个接口的信息,那么这时候getinfo接口就需要配置一下CORS头。

pay.a.com代码如下:

执行效果是失败了的,pay.a.com并没有获取到数据,这个是因为a.com还没有配置CORS头信息。

在getinfo代码上配置一下CORS头

再次请求发现能够获取到数据了,表示跨域成功。解释一下两个请求头Access-Control-Allow-Origin 用于指示哪些源站有权限访问特定资源。当一个网页试图通过JavaScript从另一个源站加载数据时,浏览器会执行跨来源HTTP请求。在这种情况下,服务器需要设置Access-Control-Allow-Origin标头来明确指定哪些源站具有权限访问资源。比如Access-Control-Allow-Origin这里设置的是http://pay.a.com:8081 就是表示允许http://pay.a.com:8081进行跨域请求。

Access-Control-Allow-Credentials 可以控制是否允许跨域请求携带凭据信息,跨域时要设置为true。

第一种情况

漏洞成因, 往往都是开发或者运维人员为了实现业务需求从而导致了配置不当造成CORS漏洞。比如配置如下

HTTP头 配置
Access-Control-Allow-Origin "Origin"
Access-Control-Allow-Credentials true

导致如上情况的后端代码可能如下:

注意:这种情况下其实也是不能成功利用CORS漏洞的。

攻击网站b.com代码如下(就是把pay.a.com网站的代码复制过去,但是发现pay.a.com能够成功访问到getinfo接口,但是b.com访问getinfo接口不成功):

b.com攻击结果

然后查看b.com向getinfo接口发送的http请求。从header来说确实是允许跨域的。

因为除了CORS保护cookie之外浏览器还有一个SameStie的保护策略,控制是否随跨站点请求发送 cookie,从而提供一些针对跨站点请求伪造攻击 (CSRF) 的保护。

SameStie可能的属性值有三个:

属性名 含义
Strict Cookie 只能在第一方环境中发送;也就是说,当获取该 Cookie 的网站与浏览器地址栏中显示的网站匹配时,才会发送 Cookie。
Lax 默认值,意味着 Cookie 不会在跨站点请求(例如加载img或iframe的请求)上发送,而是在用户从外部站点导航到源站点(例如,点击a标签)时发送。
None 意味着浏览器会通过跨站点和同站点请求发送 cookie。(必须同时设置Secure属性) Cookie 只能通过 HTTPS 协议发送。

可以看见SameStie严格程度:Strict > Lax > None那么想使得b.com跨域获取getinfo接口的信息,那么getinfo接口还得配置一下cookie。而且要把a.com换成https协议,否则Secure属性不生效。

a.com添加两行代码

可以看到b.com成功跨域访问了getinfo接口并且携带了cookie。

那么得出的结论就是,想要实现CORS劫持,要满足两个条件。
1. Access-Control-Allow-Origin可以是任意值且Access-Control-Allow-Credentials为true。2.Cookie设置了samesite为None。

第二种情况

第二种情况其实是第一种情况下面的一些限制使用。比如在实际业务中会限制跨域请求只允许子域名,但是校验却没有那么严格的情况就会出现问题。比如域名为a.com但是跨域请求校验不严格的情况大致有如下三种:

校验方式 校验内容 绕过方式
前缀校验 检测前缀是否是a.com Origin:http://a.com.b.com
后缀校验 检测后缀是否是a.com Origin:http://xxxxxxa.com
包含校验 检测是否包含a.com Origin:http://xxxxxxa.com

比如代码如下,判断了origin是否包含了a.com:

原本的方式已经失效了

那么就可以使用a.com.b.com这个域名去进行绕过过滤

第三种情况

这是对第二种情况的一个扩展,当过滤非常严格,确实只允许子域名访问的情况,但是子域名出现了xss漏洞。这个情况使用就可以使用xss植入javascript代码,让子域名替我们完成CORS劫持,并且把数据返回给到攻击网站。

比如创建一个有xss的子域名bug.a.com。代码如下。

然后可以使用xss使得bug.a.com发送跨域请求。

然后只需要iframe标签的src属性变成xsspayload即可。

第四种情况

这种情况是当Access-Control-Allow-Origin为null时的情况, 通常是开发者在网站上配置信任null源,用于调试代码。然后调试完成后没正确配置直接上线业务。

这种情况可以使用iframe来完成攻击,攻击者可从通过iframe的sandbox构造Origin为null的跨域请求。

sandbox 属性则是用来定义一个沙盒,它可以限制