CORS跨域漏洞學習
阿新 • • 發佈:2020-06-09
# 簡介
網站如果存CORS跨域漏洞就會有使用者敏感資料被竊取的風險。
跨域資源共享(CORS)是一種瀏覽器機制,可實現對位於給定域外部的資源的受控訪問。它擴充套件了同源策略(SOP)並增加了靈活性。但是,如果網站的CORS策略配置和實施不當,它也可能帶來基於跨域的攻擊。CORS並不是針對跨域攻擊(例如跨站點請求偽造(CSRF))的保護措施。
## 同源策略
這裡我們必須要了解一下同源策略:同源策略是一種限制性的跨域規範,它限制了網站與源域之外的資源進行互動的能力。起源於多年前的策略是針對潛在的惡意跨域互動(例如,一個網站從另一個網站竊取私人資料)而制定的。通常,它允許一個域向其他域發出請求,但不允許訪問響應。源由通訊協議,域和埠號組成。
SOP是一個很好的策略,但是隨著Web應用的發展,網站由於自身業務的需求,需要實現一些跨域的功能,能夠讓不同域的頁面之間能夠相互訪問各自頁面的內容。
# CORS跨域資源共享請求與響應
## 簡單請求
跨域資源共享(CORS)規範規定了在Web伺服器和瀏覽器之間交換的標頭內容,該標頭內容限制了源域之外的域請求web資源。CORS規範標識了協議頭中Access-Control-Allow-Origin最重要的一組。當網站請求跨域資源時,伺服器將返回此標頭,並由瀏覽器新增標頭Origin。
例如下面的來自站點 http://example.com 的網頁應用想要訪問 http://bar.com 的資源:
`requests`
```
1 GET /resources/public-data/ HTTP/1.1
2 Host: bar.com
3 User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre
4 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
5 Accept-Language: en-us,en;q=0.5
6 Accept-Encoding: gzip,deflate
7 Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
8 Connection: keep-alive
9 Referer: http://example.com/examples/access-control/simpleXSInvocation.html
10 Origin: http://example.com
```
`response`
```
11 HTTP/1.1 200 OK
12 Date: Mon, 01 Dec 2020 00:23:53 GMT
13 Server: Apache/2.0.61
14 Access-Control-Allow-Origin: *
15 Keep-Alive: timeout=2, max=100
16 Connection: Keep-Alive
17 Transfer-Encoding: chunked
18 Content-Type: application/xml
```
第 1~9 行是請求首部。在第10行的請求頭 Origin 表明該請求來源於 http://example.com。
第 11~18 行是來自於 http://bar.com 的服務端響應。響應中攜帶了響應首部欄位 Access-Control-Allow-Origin(第 14 行)。使用 Origin 和 Access-Control-Allow-Origin 就能完成最簡單的訪問控制。本例中,服務端返回的 Access-Control-Allow-Origin: * 表明,該資源可以被任意外域訪問。如果服務端僅允許來自 http://example.com 的訪問,該首部欄位的內容如下:
`Access-Control-Allow-Origin: http://example.com`
如果跨域請求可以包含cookie的話,在伺服器響應裡應該有這一欄位:
`Access-Control-Allow-Credentials: true`
這樣的話攻擊者就可以利用這個漏洞來竊取已經在這個網站上登入了的使用者的資訊(利用cookie)
# 漏洞利用
這裡以droabox靶場為例
![](https://imgkr.cn-bj.ufileos.com/a310a376-aa1d-4aec-ac7c-be033e5fe9b6.png)
這個介面會返回已登入的使用者的資訊資料,通過訪問該網頁的響應我們看到這裡可能存在CORS跨域資源共享漏洞
![](https://imgkr.cn-bj.ufileos.com/f59e6984-ba53-48a0-97a9-c50d47f0f393.png)
接下來我們就可以建立一個惡意的js程式碼
```
cors exp
```
訪問這個頁面就可以獲取已登入的使用者的資訊
![](https://imgkr.cn-bj.ufileos.com/80770bb8-7406-4ca7-8b3c-53bca989bf0b.png)
該惡意程式碼首先定義一個函式cors,以get形式訪問目標網址,建立XMLHttpRequest物件為xhttp,通過ajax的onreadystatechange判斷請求狀態,如果請求已完成,且相應已就緒,則彈出返回文字。
## 漏洞利用技巧
在之前我們瞭解了一些關於CORS跨域資源共享通訊的一些欄位含義,
CORS的漏洞主要看當我們發起的請求中帶有Origin頭部欄位時,伺服器的返回包帶有CORS的相關欄位並且允許Origin的域訪問。
一般測試WEB漏洞都會用上BurpSuite,而BurpSuite可以實現幫助我們檢測這個漏洞。
首先是自動在HTTP請求包中加上Origin的頭部欄位,開啟BurpSuite,選擇Proxy模組中的Options選項,找到Match and Replace這一欄,勾選Request header 將空替換為Origin:example.com的Enable框。
當我們進行測試時,看伺服器響應頭欄位裡可以關注這幾個點:
`最好利用的配置:`
Access-Control-Allow-Origin: https://attacker.com
Access-Control-Allow-Credentials: true
`可能存在可利用的配置:`
Access-Control-Allow-Origin: null
Access-Control-Allow-Credentials: true
` 很好的條件但無法利用:`
下面這組配置組合雖然看起來很完美但是CORS機制已經預設自動禁止了這種組合,算是CORS的最後一道防線
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
`單一的情況`
Access-Control-Allow-Origin:*
**總結漏洞的原因:**
1:CORS服務端的 Access-Control-Allow-Origin 設定為了 \*,並且 Access-Control-Allow-Credentials 設定為false,這樣任何網站都可以獲取該服務端的任何資料了。
2:有一些網站的Access-Control-Allow-Origin他的設定並不是固定的,而是根據使用者跨域請求資料的Origin來定的。這時,不管Access-Control-Allow-Credentials 設定為了 true 還是 false。任何網站都可以發起請求,並讀取對這些請求的響應。意思就是任何一個網站都可以傳送跨域請求來獲得CORS服務端上的資料。
# 其他可能利用漏洞的地方
## 解析Origin頭時出錯
一些支援從多個來源進行訪問的應用程式通過使用允許的來源白名單來實現。收到CORS請求後,會將提供的來源與白名單進行比較。如果來源出現在白名單中,那麼它會反映在Access-Control-Allow-Origin標題中,以便授予訪問許可權。例如,web應用收到一個正常的請求:
```
GET /data HTTP/1.1
Host: bar.com
...
Origin: https://example.com
```
web應用根據其允許的來源列表檢查當前請求資源的來源,如果在列表中,則按以下方式反映該來源:
```
HTTP/1.1 200 OK
...
Access-Control-Allow-Origin: https://example.com
```
但在檢測來源是否存在於白名單時經常可能出現問題,一些網站可能會允許其所有的子域(包括尚未存在未來可能存在的子域)來進行訪問,或者允許其他網站的域以及其子域來訪問請求。這些請求一般都通過萬用字元或者正則表示式來完成,但是如果這其中出現錯誤可能就會導致給予其他未被授權的域訪問許可權。例如:
例如,假設一個應用程式授予對以下列結尾的所有域的訪問許可權:
examplecom
攻擊者可能可以通過註冊域來獲得訪問許可權:
exeexample.com
或者,假設應用程式授予對所有以example.com開頭的域訪問許可權,攻擊者就可以使用該域獲得訪問許可權:
example.com.evil-user.net
## 利用相互受CORS信任的域來進行XSS
假如兩個互相受信任的源,如果其中一個網站存在XSS,攻擊者就可以利用XSS注入一些JavaScript程式碼,利用這些程式碼對信任其源的另一個網站進行敏感資訊的獲取。
如果進行CORS請求時網站響應:
```
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://vulnerable.com
Access-Control-Allow-Credentials: true
```
就可以利用XSS漏洞在vulnerable.com網站上使用下面的URL來通過檢索API金鑰:
`https://vulnerable.com/?xss=`
## 白名單中的null值
CORS協議的一個重要安全前提是跨域請求中的Origin頭不能被偽造,這個前提並不是總是成立。Origin頭最早被提出用於防禦CSRF攻擊,它的語法格式在RFC 6564中被定義。RFC 6564規定,如果請求來自隱私敏感上下文時,Origin頭的值應該為null,但是它卻沒有明確界定什麼是隱私敏感上下文。
CORS協議複用了Origin頭,但在CORS標準中同樣缺乏對跨域請求Origin中null明確的定義和限制。有些開發者在網站上配置信任 null,用於與本地file頁面共享資料,如下所示:
Access-Control-Allow-Origin: null
Access-Control-Allow-Credentials: true
在這種情況下,攻擊者可以使用各種技巧來生成跨域請求,該請求構造的Origin為null值。這將滿足白名單的要求,從而導致跨域訪問。例如,可以使用iframe以下格式的沙盒跨域請求來完成:
```
```
這就意味著任何配置有`Access-Control-Allow-Origin: null`和`Access-Control-Allow-Credentials:true`的網站等同於沒有瀏覽器SOP的保護,都可以被其他任意域以這種方式讀取內容。
## CORS漏洞的自動化掃描
github上提供了一個關於掃描CORS配置漏洞的指令碼
https://github.com/chenjj/CORScanner
CORScanner是一個python工具,旨在發現網站的CORS錯誤配置漏洞。它可以幫助網站管理員和滲透測試人員檢查他們針對的域/ URL是否具有不安全的CORS策略。
![](https://imgkr.cn-bj.ufileos.com/b17ffb53-1136-439f-a049-2f292de90fc6.png)
但是這個好像不能掃描特定介面的
# 預防CORS漏洞
CORS漏洞主要是由於配置錯誤而引起的。所以,預防漏洞變成了一個配置問題。下面介紹了一些針對CORS攻擊的有效防禦措施。
1. 正確配置跨域請求
如果Web資源包含敏感資訊,則應在Access-Control-Allow-Origin標頭中正確指定來源。
2. 只允許信任的網站
看起來似乎很明顯,但是Access-Control-Allow-Origin中指定的來源只能是受信任的站點。特別是,使用萬用字元來表示允許的跨域請求的來源而不進行驗證很容易被利用,應該避免。
3. 避免將null列入白名單
避免使用標題Access-Control-Allow-Origin: null。來自內部文件和沙盒請求的跨域資源呼叫可以指定null來源。應針對私有和公共伺服器的可信來源正確定義CORS頭。
4. 避免在內部網路中使用萬用字元
避免在內部網路中使用萬用字元。當內部瀏覽器可以訪問不受信任的外部域時,僅靠信任網路配置來保護內部資源是不夠的。
5. CORS不能替代伺服器端安全策略
CORS定義了瀏覽器的行為,絕不能替代伺服器端對敏感資料的保護-攻擊者可以直接從任何可信來源偽造請求。因此,除了正確配置的CORS之外,Web伺服器還應繼續對敏感資料應用保護,例如身份驗證和會話