);
错误 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漏洞扫描工具
https://github.com/chenjj/CORScanner
CORS安全配置最佳实践
1. 不要盲目反射 Origin头
2. 严格校验 Origin 头,避免出现权限泄露
3. 不要配置 Access-Control-Allow-Origin: null
4. HTTPS 网站不要信任HTTP 域
5. 不要信任全部自身子域,减少攻击面
6. 不要配置 Origin:*和 Credentials: true
7. 增加 Vary: Origin 头
参考链接:
https://eviloh.github.io/2018/08/06/CORS%E9%85%8D%E7%BD%AE%E9%94%99%E8%AF%AF%E6%A3%80%E6%B5%8B%E6%96%B9%E6%B3%95/
知识要大家一起分享,但带上原文链接是对作者的尊重。