跨站资源共享(CORS)漏洞的误配置及检测方法

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

跨站资源共享(CORS)漏洞的误配置及检测⽅法
基本知识
同源策略(Same Origin Policy, SOP)
同源策略是浏览器级别的安全机制。

它的核⼼观点是,来⾃不同源(域名、端⼝或者协议有⼀项不同都算)的Web应⽤不共享任何资源。

例如,在⽗页⾯中建⽴⼀个iframe标签指向另⼀个域名,⽗页⾯和iframe属于不同源,不能相互读取DOM树。

⽗页⾯只能控制iframe发送get或post请求,却不能读取请求的内容。

但有时候,我们需要在不同域的web应⽤之间交换数据,这时候有以下⼏种常⽤的跨域⽅法:JSONP,window.postMessage(),CORS。

跨域资源共享(Cross-Origin Resource Sharing, CORS)
CORS的原理是,当我们要进⾏跨域请求时,在服务端的响应头中加⼊相应header,通知浏览器添加特例放宽同源策略的限制。

重要的响应头有:
- Access-Control-Allow-Origin: 服务端接受来⾃的跨域请求
- Access-Control-Allow-Credentials: true表⽰是否允许发送Cookie,true即发送cookie
如果要和通信,且可以⽤如下代码开启CORS响应头:
<?php
header("Access-Control-Allow-Origin: ");
header("Access-Control-Allow-Credentials: true");
>
⽽可以使⽤下⾯的js代码与通信,读取的内容:
var xhr=new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == XMLHttpRequest.DONE) {
alert(xhr.responseText);
}
}
xhr.open(“GET“, ”/api“, true);
xhr.withCredentials = true;
xhr.send();
CORS误配置及检测⽅法
检测CORS配置错误相对⽐较简单,因为⼤部分服务器都是使⽤请求包的Origin头进⾏控制的,⽽我们可以任意修改Origin头。

只要对⽐响应头中ACAO和ACAC的变化,便可以判断是否存在漏洞。

基本脚本如下:
import requests
acao = ''
acac = ''
headers = {'Origin': 'test'}
r = requests.get('http://192.168.140.129/cors/1.php', headers=headers)
if'Access-Control-Allow-Origin'in r.headers:
acao = r.headers['Access-Control-Allow-Origin']
if'Access-Control-Allow-Credentials'in r.headers:
acac = r.headers['Access-Control-Allow-Credentials']
print("Access-Control-Allow-Origin: " + acao)
print("Access-Control-Allow-Credentials: " + acac)
反射Origin头
为了安全考虑,ACAO头默认不允许填写多个域名。

有些开发者为了⽅便,直接在Access-Control-Allow-Origin中反射请求的Origin值。

作为ACAO的域名,这样使得所有⼈都可以轻易访问该域名内容,窃取隐私数据。

服务端代码为:
<?php
header("Access-Control-Allow-Origin: " . $_SERVER['HTTP_ORIGIN']);
header("Access-Control-Allow-Credentials: true");
>
错误 Nginx 配置⽰例:
add_header "Access-Control-Allow-Origin" $http_origin;
add_header “Access-Control-Allow-Credentials” “true”;
这种配置⾮常危险,相当于信任任意⽹站,给攻击者⽹站敞开了⼤门。

任意攻击者⽹站可以直接跨域读取其资源内容。

检测⽅法:
使⽤不同Origin头请求同⼀个服务器,查看响应头中Access-Control-Allow-Origin是否总是与Origin相同。

Origin校验错误
有些Origin检测的⽅法⽐较宽松,造成只匹配了前缀、后缀、没有转义”.”等情况。

检测⽅法:
先发送⼀个请求,得到CORS头后,在其中加⼊前缀、后缀以及将”.”替换成任意字符,查看响应头是否同步变化
信任null
有些web应⽤为了与本地file页⾯共享数据,将ACAO头设置为Null,但攻击者可以使⽤如下代码发送Origin为Null的请求。

<iframe sandbox="allow-scripts allow-top-navigation allow-forms" src='data:text/html,<script>var xhr=new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == XMLHttpRequest.DONE) {
alert(xhr.responseText);
}
}
xhr.open("GET", "http://45.32.105.30:8080", true);
xhr.withCredentials = true;
xhr.send();</script>'></iframe>
检测⽅法:
直接检测返回头CORS是否是NULL即可
HTTPS域信任HTTP域
如果https域的应⽤信任⾮http域,那么攻击者可以先劫持受信任的http域,然后通过这个域发送跨域请求到https站,从⽽盗取信息。

检测⽅法:
直接检测https站点返回头CORS是否信任http即可
信任⾃⾝任意⼦域
有些应⽤过分信⽤⾃⾝⼦域,当⼦域中发⽣XSS时,会放⼤XSS的危害。

检测⽅法:
在请求Origin中发送⽬标站点的⼦域名,检查返回头ACAO
Origin: *与 Credentials: true 共⽤
如果是开放的公共资源,origin才会设置成通配符”*”,这种资源不应该允许携带cookie等访问。

浏览器会对下⾯这种误配置报错:
Access-Control-Allow-Origin:*
Access-Control-Allow-Credentials:true
这就意味着,Access-Control-Allow-Origin:*只能⽤于共享公开资源。

检测⽅法:
直接检查⽬标返回头即可。

缺少Vary: Origin头
如果⼀个资源享有多个域名,它需要对不同域名的请求包⽣成不同的ACAO头。

如果⼀个请求的响应被缓存,且返回中没有Vary: Origin字段,可能会导致其它域名的请求失效。

检测⽅法:
⽆法检测,因为我们不知道⼀个服务器是否共享多个域名。

CORS漏洞扫描⼯具
CORS安全配置最佳实践
1. 不要盲⽬反射 Origin头
2. 严格校验 Origin 头,避免出现权限泄露
3. 不要配置 Access-Control-Allow-Origin: null
4. HTTPS ⽹站不要信任HTTP 域
5. 不要信任全部⾃⾝⼦域,减少攻击⾯
6. 不要配置 Origin:*和 Credentials: true
7. 增加 Vary: Origin 头
参考链接:。

相关文档
最新文档