深入了解跨站WebSocket劫持漏洞的原理和防範

Mondo 科技 更新 2024-02-12

跨站WebSocket漏洞的原理、檢測和修復。

WebSocket 是 HTML5 的新特性之一,它引起了開發人員的注意,因為它使客戶端(主要是瀏覽器)能夠提供對套接字的支援,從而在客戶端和伺服器之間提供基於單個 TCP 連線的雙向通道。

適用於實時性要求高的應用,如***遊戲、不同裝置之間的資訊同步等。 資訊的實時同步一直是乙個技術挑戰,在WebSockets出現之前,常見的解決方案是輪詢和Comet技術,但這些技術增加了設計複雜性,給網路和伺服器帶來了額外的負擔,並且在重負載下效率相對較低,導致應用程式的可擴充套件性有限。 對於此類應用程式的開發人員來說,WebSocket 技術是讀者登入 WebSocket 的強大工具組織**的特色案例,以及它提供的websocket和comet效能的比較分析。

近年來,WebSocket技術在各種實際應用中被開發人員廣泛使用。 不幸的是,與 WebSocket 相關的安全漏洞也被揭露出來,其中最有可能的是跨站 WebSocket 劫持漏洞。 本文將簡單介紹跨站WebSocket漏洞的原理、檢測方法和修復方法,希望能幫助讀者在實際工作中規避這個已知的安全漏洞。

為了說明跨站WebSocket劫持漏洞的原理,本文將簡要介紹一下WebSocket協議的握手和切換過程。 建議有興趣的讀者閱讀參考文獻中提供的 RRFC 6455 規範,以深入研究 WebSocket 協議。

任何了解 websocket 技術的人都知道它ws://http://那麼 websockets 和 http 之間是什麼關係呢? 筆者對這個問題的理解是,WebSocket 是 HTML5 引入的一種新協議,與 HTTP 協議本身的內容無關。 WebSocket 是一種永續性協議,而 HTTP 是一種非永續性連線。

如前所述,WebSocket 提供全雙工通訊,通常稱為與 Web 的 TCP 連線,但 TCP 通常處理位元組流(獨立於訊息),而 WebSocket 則基於 TCP 實現訊息流。 WebSocket 也類似於用於握手連線的 TCP,與 TCP 不同,WebSocket 基於 HTTP 協議。 作者使用 Chrome 開發者工具收集 WebSocketECHO 測試服務的協議握手請求和響應如清單 1 和 2 所示。

清單 1WebSocket 協議公升級請求。

get ws: http/1.1host: echo.websocket.orgconnection: upgradepragma: no-cachecache-control: no-cacheupgrade: websocketorigin: 13user-agent: mozilla/5.0 (macintosh; intel mac os x 10_11_4) chrome/49.0.2623.110accept-encoding: gzip, deflate, sdchaccept-language: en-us,en;q=0.8,zh-cn;q=0.6cookie: _gat=1; _ga=ga1.2.2904372.1459647651; jsessionid=1a9431cf043f851e0356f5837845b2ecsec-websocket-key: 7arps0ajshn8bx5dci1kkq==sec-websocket-extensions: permessage-deflate; client_max_window_bits
熟悉HTTP的人可以發現WebSocket的核心,是的,這是兩條連線線:upgrade和upgrade:websocket。 這兩行相當於告訴伺服器:我想請求切換到 websocket 協議。

清單 2WebSocket 協議公升級響應。

http/1.1 101 web socket protocol handshakeaccess-control-allow-credentials: trueaccess-control-allow-headers: content-typeaccess-control-allow-headers: authorizationaccess-control-allow-headers: x-websocket-extensionsaccess-control-allow-headers: x-websocket-versionaccess-control-allow-headers: x-websocket-protocolaccess-control-allow-origin: upgradedate: sun, 03 apr 2016 03:09:21 gmtsec-websocket-accept: ww9bl95vtfjdbphdfivy7csoado=server: kaazing gatewayupgrade: websocket
一旦伺服器端返回 101 響應,websocket 協議切換就完成了。 然後,伺服器端可以使用相同的埠從http://https://切換到ws://wss://。協議切換完成後,瀏覽器和伺服器可以使用 WebSocket API 相互傳送和接收文字和二進位訊息。

以下是一些與安全相關的重要標頭引數,sec-websocket-key 和 sec-websocket-accept。 這涉及 websocket 安全功能,其中客戶端負責生成乙個 base64 編碼的隨機數作為 sec-websocket-key,伺服器將生成乙個 GUID 以及客戶端的隨機數,以生成乙個雜湊金鑰,該雜湊金鑰作為 sec-websocket-accept 返回給客戶端。 這可用於避免快取代理和請求重播。

細心的讀者可能還會注意到許多其他以“sec”開頭的與 websocket 相關的標頭。 其實這也是 websocket 設計器出於安全考慮的特殊設計,以 “sec-” 開頭的 header 可以避免被瀏覽器指令碼讀取,這樣攻擊者就無法使用 xmlhttprequest 偽造 websocket 請求來執行跨協議攻擊,因為 xmlhttprequest 介面不允許設定以 sec- 開頭的 header。

雖然 WebSocket 協議在設計時就考慮到了安全性,但隨著 WebSocket 技術的普及,安全工作者也慢慢發現了一些與 WebSocket 相關的安全漏洞,比如 Wireshark 漏洞 CVE-2013-3562 (Wireshark 18.7 之前 18.EPAN 在 X 版本的 WebSocket 解析器中分析 packet-websocket。C 語言的 'tvb unmasked' 函式存在多個整數符號錯誤,遠端攻擊者可利用這些錯誤通過惡意資料包造成拒絕服務。

Asterisk WebSocket Server 中的 DOS 漏洞 CVE-2014-9374(WebSocket Server 模組中存在乙個雙重釋放漏洞,遠端攻擊者可以利用該漏洞傳送長度為零的幀,從而造成拒絕服務)。 這兩個 DDoS 漏洞與 WebSocket 協議本身和 WebSocket 應用程式關係不大。 然而,在 2015 年,Cisco 的 Brian Manifold 和 Nebula 的 Paul McMillan 報告了 OpenStack Nova 控制台中的乙個 WebSocket 漏洞 (CVE-2015-0259),該漏洞受到廣泛關注,並在許多 WebSocket 應用程式中被發現。

事實上,該漏洞是在 2013 年由德國白帽黑客 Christian Schneider 發現並公開的,他將其命名為跨站點 WebSocket 劫持 (CSWSH)。 跨站點 websocket 劫持相對有害,更容易被開發人員忽視。

什麼是跨站WebSocket劫持漏洞,如前所述,為了建立全雙工通訊,客戶端需要基於HTTP握手切換到WebSocket協議,而這種協議公升級的過程是潛在的致命弱點。 如果你仔細觀察上面的握手獲取請求,你可以看到cookie標頭將網域名稱下的所有cookie都傳送到了伺服器。

如果你有機會閱讀 websocket 協議 (10第 5 章 客戶端身份驗證)發現 WebSocket 協議沒有指定伺服器在握手階段應如何對客戶端進行身份驗證。伺服器可以使用任何HTTP伺服器的客戶端認證機制,如cookie、HTTP基本認證、TLS認證等。 因此,對於大多數 Web 應用程式,客戶端身份驗證應為 Cookie,例如 sessionid 或 HTTP 身份驗證標頭引數。 熟悉跨站請求偽造(CSRF)的朋友應該能夠想到黑客可能會偽造握手請求以繞過身份驗證。

因為 websocket 的客戶端不侷限於瀏覽器,所以 websocket 規範的來源不必相同(有興趣的讀者可以閱讀規範 10。2 章用於 Origin 規範)。所有瀏覽器都會傳送源頭,如果伺服器不針對源頭進行驗證,則可能導致跨站點 websocket 劫持攻擊。

例如,如果使用者登入到乙個應用程式,如果他被誘騙訪問社交**的惡意網頁,則該惡意網頁將在元素中植入乙個 websocket 握手請求,以請求 websocket 連線到目標應用程式。 開啟惡意網頁後,會自動發起以下請求: 請注意,origin 和 sec-websocket-key 都是由瀏覽器自動生成的,Cookie 等認證引數由瀏覽器自動上傳到目標應用的伺服器端。 如果伺服器檢查來源失敗,請求會成功切換到 WebSocket 協議,惡意網頁可以成功繞過身份認證連線到 WebSocket 伺服器,然後竊取伺服器傳送的資訊,或者向伺服器傳送偽造的資訊來篡改伺服器的資料。

有興趣的讀者可以將此漏洞與CSRF進行對比,CSRF主要通過惡意網頁悄悄發起資料修改請求,不會造成資訊洩露問題,而跨站WebSocket偽造攻擊不僅可以修改伺服器資料,還可以控制整個雙向通訊通道進行讀取和修改。 這就是為什麼克里斯蒂安將漏洞命名為劫持,而不是請求偽造。

清單 3被篡改的 websocket 協議公升級請求。

get ws: http/1.1host: echo.websocket.orgconnection: upgradepragma: no-cachecache-control: no-cacheupgrade: websocketorigin: 13accept-encoding: gzip, deflate, sdchaccept-language: en-us,en;q=0.8,zh-cn;q=0.6cookie: _gat=1; _ga=ga1.2.290430972.14547651; jsessionid=1a9431cf043f851e0356f5837845b2ecsec-websocket-key: 7arps0ajshn8bx5dci1kkq==sec-websocket-extensions: permessage-deflate; client_max_window_bits
在這一點上,熟悉 j**ascript 跨域資源訪問的讀者可能會持懷疑態度。 如果 HTTP 響應沒有指定 “access-control-allow-origin”,瀏覽器指令碼將無法訪問跨域資源,沒錯,這就是大家熟知的跨域資源共享(CORS),確實是 HTML5 帶來的新特性之一。 不幸的是,跨域資源共享不適用於 websocket,它沒有指定如何跨域處理它們。

了解了跨站WebSocket劫持漏洞的原理後,很容易想到這個漏洞的檢測方法,重點是重放WebSocket協議公升級請求。 簡單來說,就是使用攔截 websocket 握手請求的工具,修改請求中的源頭,然後重新傳送請求,看看伺服器是否能成功返回 101 響應。

如果連線失敗,則 websocket 是安全的,因為它會正確拒絕來自不同源的連線請求。 如果連線成功,通常證明是伺服器沒有進行源頭檢查,為了嚴謹起見,最好進一步測試一下 websocket 訊息是否可以傳送,如果 websocket 連線能夠傳送和接受訊息,則充分證明跨站 websocket 劫持漏洞的存在。

為了演示如何測試和修復這個漏洞,筆者編寫了乙個簡單的 WebSocket 應用,實現了基於 Jaas 的 HTTP Basic 認證,讀者可以將這個程式部署到 Tomcat 進行測試。 開啟客戶端網頁後,先登入,然後點選“連線”按鈕通過j**ascript建立websocket連線,然後點選“傳送”按鈕將問題提交到伺服器,伺服器實時確認收到查詢請求,5秒後將結果推送到客戶端。

在測試工具方面有很多選擇,出於許可原因,我使用開源 OWASP ZAP v24.3。這裡簡單提一下,測試過程主要是基於測試工具的**,攔截 websocket 握手請求和 websocket 訊息通訊,然後通過工具修改源站後重新傳送請求,連線成功後重新傳送 websocket 客戶端訊息。 上述所有功能都可以通過任何商業安全測試工具完成。

1. 首先在 Firefox 中配置 Zap,然後瀏覽整個 WebSocket 應用程式。 如下圖所示,請求頭中會出現 HTTP 基本授權資訊,表示登入成功。

圖1WebSocket 協議公升級請求。

2. 右鍵單擊並選擇重新傳送 WebSocket 協議公升級請求,將源修改為任何其他**,然後單擊傳送。

圖2篡改 WebSocket 協議公升級請求。

3. 點選響應選項卡,可以看到伺服器端返回101,即協議握手成功。

圖3WebSocket 協議握手成功。

4. 進一步測試 websocket 訊息是否可以重傳。 如下圖所示,右鍵點選客戶端傳送的第一條websocket訊息,選擇Retransmit,輸入測試訊息“www”,點選傳送,可以看到ZAP已經依次收到了伺服器返回的兩條訊息。 這充分證明了測試應用站點存在跨站WebSocket劫持漏洞。

圖4重新傳送客戶端 websocket 訊息。

上面已經介紹了跨站websocket劫持漏洞的原理和檢測方法,相信讀者已經了解了它的危害,那麼我們來談談如何防止這個漏洞。 這個漏洞的原理聽起來有點複雜,但幸運的是它測試起來相對簡單,所以很容易修復。 很多讀者會認為,這不僅僅是檢查伺服器中的 origin 引數**。 是的,檢查原產地是必要的,但還不夠。 如果客戶端傳送的源資訊來自其他域,建議伺服器拒絕請求並發回 403 錯誤響應以拒絕連線。

作者使用 J**A EE 技術編寫了乙個 WebSocket 測試應用,J**A EE WebSocket API 提供了乙個配置器,允許開發者覆蓋配置來攔截和檢查協議握手過程。 作者在文章附錄中已經將這部分內容收錄在了原始碼**中,下面對一些核心類和配置進行了簡要介紹。 如果您不熟悉 J**A EE WebSocket API,建議您先檢視相關規格。

1. 首先,為 websocket 伺服器終端編寫乙個配置器,繼承並重寫 checkorigin 方法,如清單 4 所示。 注意作者忽略了沒有源頭的場景,這取決於每個應用的實際情況,如果有非瀏覽器客戶端,則需要新增此檢查。 還建議非瀏覽器客戶端檢視下面的令牌機制。

清單 4WebSocket 源檢查配置器。

public class customconfigurator extends serverendpointconfig.configurator }
2. 然後將配置器關聯到 websocket 伺服器。

清單 5配置 websocket 源檢查。

@serverendpoint(value = "/query", configurator = customconfigurator.class)public class websockettestserver }
3. 重新打包並發布 websocket 應用程式。

有興趣的讀者可以自己試試,如果補上以上**後重播被篡改的websocket握手協議請求,會收到403錯誤。

以上看起來不錯,但僅僅檢查來源是不夠的,別忘了,如果 websocket 客戶端不是瀏覽器,來自非瀏覽器客戶端的請求根本沒有來源。 除此之外,我們還需要記住,惡意網頁可以偽造源頭資訊。 乙個更激進的解決方案是借鑑CSRF的代幣機制。

由於篇幅關係,筆者不會詳細發布整個設計,但建議讀者參考以下總結設計,以提高 websocket 應用的安全性。

服務端為每個 websocket 客戶端生成乙個唯一的一次性令牌; 客戶端使用令牌作為 WebSocket 連線 URL 的引數(例如,WS:傳送到伺服器進行 WebSocket 握手連線; 伺服器驗證令牌是否正確,如果正確,則標記丟棄,不再重複使用,websocket握手連線成功。 如果令牌認證失敗或認證失敗,則返回 403 錯誤。 該方案中的令牌設計是關鍵,筆者推薦的方案是為登入使用者生成乙個安全隨機並儲存在會話中,然後使用對稱加密(如AES GCM)將這個安全隨機值加密為令牌,並將加密後的令牌傳送給客戶端進行連線。 這允許每個會話有乙個唯一的隨機數,每個隨機數可以通過對稱加密生成多個一次性令牌。 即使使用者通過不同的終端通過 websocket 連線到伺服器,伺服器仍然可以在保證 Token 唯一且使用一次的前提下,將來自不同渠道的資訊與同一使用者關聯。

可能還有另外一種設計思路,就是給 websocket 訊息新增 token 和身份資訊,但我覺得這種設計與 websockets 的設計思路背道而馳,增加了不必要的網路負載。 歡迎讀者提供更好的設計方案。

在本文中,筆者與讀者分享了對WebSocket協議握手的理解,並在此基礎上解釋了WebSocket跨站劫持漏洞的原理。 如本文所述,這是 Web 應用程式中唯一乙個廣為人知的 websocket 漏洞。 同時,筆者還分享了跨站WebSocket劫持漏洞的檢測方法,並介紹了基於J**A EE技術的漏洞修復,以及基於token機制的更全面的安全解決方案。

相關問題答案

    深入了解小程式團購

    微信小程式是當今市場上最熱門的工具之一。通過它,使用者可以直接在微信平台上購買商品或服務,而無需任何額外的應用程式。小程式 是特殊的購物方式之一,它允許使用者以較低的價格購買商品或服務 .小程式流程 首先,使用者需要在微信中搜尋並開啟想要的小程式。在小程式的首頁,通常有 或 群組 等選項供選擇。點選...

    Excel函式教程:深入了解ACOS函式並應用

    在Excel中,函式是乙個非常強大的工具,可以幫助我們執行各種計算 分析和處理資料的操作。本教程將重點介紹ACOS函式的範圍,並提供一些示例來幫助讀者更好地理解和應用該函式。ACOS 函式是乙個三角函式,用於計算給定數字的反余弦值。其語法如下 acos number ACOS函式在許多領域都有廣泛的...

    對安全第一的深刻理解和實踐

    安全第一 深入理解和實踐。在我們的日常生活和工作中,安全第一的理念是我們必須時刻牢記的重要原則。這不僅關係到我們的生命安全,還直接影響著我們的生活質量。本文將就安全第一的重要性 如何實踐安全 安全能產生的積極影響,以及現實生活中可能遇到的安全挑戰以及如何應對這些挑戰提供具體的案例研究。安全第一的理念...

    深入了解用於生成和格式化數字序列的 seq 命令

    在電腦科學和資料處理中,數字序列的生成和格式化是乙個常見的要求。seq 命令是 UNIX 和 Linux 系統中的內建工具,它提供了此功能,並因其簡單高效的操作方式而受到稱讚。下面,我們將仔細研究 seq 命令的工作原理及其作用。首先,seq 命令是 sequence 的縮寫,專門用於生成和列印數字...

    深入了解防爆冰箱創新設計及行業應用

    在特定的工業環境中,如實驗室 化工廠和石化領域,通常儲存易燃 易爆或化學敏感物質。在這些環境下,傳統冰箱存在安全隱患,因此防爆冰箱成為不可或缺的裝置。本文將深入探討防爆冰箱在各行業的創新設計特點和應用。 防爆冰箱的設計特點。防爆內部結構 防爆冰箱內部設計避免任何火花或電弧,保證即使在存放易燃物質時也...