跨域资源共享(CORS)是一种放宽同源策略的机制,它允许浏览器向跨源服务器,发出请求XMLHttpRequest(XHR),从而克服了 AJAX 只能同源使用的限制,以使不同的网站可以跨域获取数据。
那么什么是跨域呢?
当协议、域名、端口全部相同时,才算同域,所以跨域就很显然了。
而CORS定义了两种请求方式:
简单请求和
非简单请求。
简单请求就是使用设定的请求方式请求数据,而
非简单请求则是在使用设定的请求方式请求数据前,先发送一个OPTIONS预检请求,验证请求源是否为服务端允许源,只有验证为允许后才会再次发送一次请求用于数据传输。
CORS运行机制:在浏览器进行请求时,自动在请求头中添加Origin字段信息,服务端通过验证Origin字段来判断请求是否被允许,从而实现浏览器跨域资源访问。(
跨域只在浏览器端实现)
跨域字段解释:
Access-Control-Allow-Origin:该字段是必须的。它的值要么是请求时Origin字段的值,要么是一
个*,表示接受任意域名的请求。
Access-Control-Allow-Credentials:该字段可选。它的值是一个布尔值,表示是否允许发送Cookie。默认情况下,Cookie不包括在CORS请求之中。当设置为true时,即表示服务器明确许可,Cookie可以包含在请求中,一起发给服务器。这个值也只能设为true,如果服务器不要浏览器发送Cookie,删除该字段即可。
Access-Control-Expose-Headers:该字段可选 。CORS请 求 时, XMLHttpRequest 对象的
getResponseHeader()方法只能拿到 6 个基本字段:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。如果想拿到其他字段,就必须在Access-Control-Expose-Headers参数里指定。
个*,表示接受任意域名的请求。
Access-Control-Allow-Credentials:该字段可选。它的值是一个布尔值,表示是否允许发送Cookie。默认情况下,Cookie不包括在CORS请求之中。当设置为true时,即表示服务器明确许可,Cookie可以包含在请求中,一起发给服务器。这个值也只能设为true,如果服务器不要浏览器发送Cookie,删除该字段即可。
Access-Control-Expose-Headers:该字段可选 。CORS请 求 时, XMLHttpRequest 对象的
getResponseHeader()方法只能拿到 6 个基本字段:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。如果想拿到其他字段,就必须在Access-Control-Expose-Headers参数里指定。
在CORS跨域请求中,响应头的参数可能存在以下几种情况:
①
Access-Control-Allow-Origin: xxx.xxx.xxx
Access-Control-Allow-Credentials: true
②
Access-Control-Allow-Origin: null
Access-Control-Allow-Credentials: true
③
Access-Control-Allow-Origin: Null
Access-Control-Allow-Credentials: true
④
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
⑤
Access-Control-Allow-Origin: *
在进行CORS漏洞测试时,要注意响应头所返回的信息。
测试代码如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>corstest</title>
</head>
<body>
<script>
function corstest() {
var xhr = new XMLHttpRequest(); //新建xhr对象
xhr.onreadystatechange = function () { //当readyState改变时会触发onreadystatechange事件
if(xhr.readyState == 4){ //readyState为4时表示数据接收完成
alert(xhr.responseText);
}
}
xhr.open("GET",'http://x.x.x.x/user',true); //初始化请求,使用get方法请求,且为异步请求
xhr.send();
}
corstest();
</script>
</body>
</html>
CORS防御方案:
1、减少“Access-Control-Allow-Methods”所允许的请求方法。
2、对origin请求头参数做严格校验,可做白名单验证。
3、非必要情况下,禁止
使用"Access-Control-Allow-Credentials: true"