趙娟娟 劉昌華
(武漢輕工大學數學與計算機學院 武漢 430023)
(zhaojj0228@163.com)
隨著互聯網的快速發展,Web應用已成為我們生活中必不可少的一部分.在實時通信方面一般對于即時性有較高的要求,目前針對實時性問題主要有輪詢以及其他的服務器推送技術等方法[1],但這些方法都是基于Http請求的,使用Http協議需要不斷向服務器發出請求,然而Http請求會包含較長的頭部,這樣會浪費很多資源.在這種情況下,W3C定義了WebSocket協議[2],相比較Http協議,WebSocket能更好地節省服務器資源和帶寬,并且能夠更實時地進行通信.
近年來隨著WebSocket被廣泛使用,也出現了一些關于WebSocket的安全漏洞[3].Wireshark1.8.7之前的1.8.x版本中WebSocket解析器中的epandissectorspacket-websocket.c的tvb_unmasked函數中存在多個整數符號錯誤,遠程攻擊者可通過惡意的數據包利用這些漏洞造成拒絕服務攻擊.2013年德國的白帽黑客 Christian Schneider 發現并公開了發現跨站劫持漏洞(cross site WebSocket hijacking).跨站點WebSocket劫持相對危害較大,也更容易被開發人員忽視.針對WebSocket漏洞問題,近年來也有一些學者作了研究,朱軍[4]基于Node平臺提出使用自定義子協議Wsguard防御跨站劫持的策略;曾德愚[5]提出在服務器端代碼中增加Origin檢查機制修復漏洞,如果瀏覽器發送的Origin信息來源不同,則服務器端拒絕請求并發回拒絕連接403錯誤;Karlstr?m[6]提出2次驗證Origin防御跨站劫持,限制連接數量緩解DoS攻擊,使用內容深度檢測抵御注入攻擊等策略.
本文在總結前人研究的基礎上,針對WebSocket跨站劫持漏洞提出WebSocket子協議“Security-WebSocket”.該子協議使用typescript語言完成系統實現,協議要求每次在WebSocket連接建立完成之后,需要使用WebSocket通道進行2次身份認證,認證通過之后,服務端使用AES(advanced encryption standard)加密算法隨機生成密鑰后發送給客戶端,客戶端收到后按照約定的密鑰進行數據加密并攜帶認證信息和加密算法使用的偏移量一起發送到服務器.以后的每次通信都是需要將消息加密傳輸,并且每次發送消息都需要攜帶2次加密的認證憑證和偏移量,否則WebSocket連接將被中斷.
WebSocket于2008年誕生,2011年成為國際標準,目前所有的瀏覽器都已支持該協議.它是HTML5 開始提供的一種在單個TCP 連接上進行全雙工通信的協議,WebSocket 使得客戶端和服務器之間的數據交換變得更加簡單,允許服務端主動向客戶端推送數據[7].在 WebSocket API 中,瀏覽器和服務器只需要完成一次握手,兩者之間就可以直接創建持久性的連接,并進行雙向數據傳輸.客戶端和服務器間建立連接示意圖如圖1所示:

圖1 WebSocket連接握手
密碼學中的高級加密標準,又稱Rijndael加密法,是美國聯邦政府采用的一種區塊加密標準[8].AES為分組密碼,即把明文分成多組,每組長度相等,每次加密1組數據,直到加密完成整個明文.用初始向量和密鑰加密第1組數據,然后把第1組數據加密后的密文重新賦值給IV(初始偏移量),再進行第2組加密,循環進行直到結束.具體分組加密過程如圖2所示:

圖2 AES算法加密過程
本文在研究WebSocket協議的基礎上設計了子協議Security-WebSocket,該子協議可以預防跨站劫持漏洞,完成客戶端身份認證,實現數據加密傳輸等功能.為了預防跨站劫持攻擊,該子協議實現了在客戶端和服務端建立連接時首先通過約定的身份認證標識驗證客戶端身份,在身份驗證無誤后方可進行協商密鑰,最后通過協商的密鑰進行加密數據進行通信.大致過程如下:
1) 客戶端和服務端建立WebSocket連接;
2) 客戶端發送約定的標識信息;
3) 服務器確認收到標識信息后發送加密密鑰;
4) 客戶端確認收到密鑰后進行數據加密并攜帶身份標識以及隨機生成的偏移量發送到服務端;
5) 服務端收到信息后首先根據身份標識確認是對應的客戶端后再解密信息;
6) 依次循環4)5)步直到通信結束.
客戶端和服務器連接時,會在發送Http請求時在請求頭中攜帶Upgrade字段發送到服務端,服務器收到請求后發現該請求要求將Http協議更新為WebSocket協議,服務器返回相應碼101表示協議升級成功[9].從以上可以看出WebSocket只有在建立連接的過程中需要進行身份認證,在連接建立成功后再無身份認證過程.也就是我們只要復制請求就可以直接連接服務器,這樣就會導致惡意網頁冒充客戶端竊取服務器發來的消息進行通信.子協議Security-WebSocket的設計主要是防御WebSocket 跨站劫持漏洞,主要的作用就是增加了傳輸過程中身份認證,加密傳輸,這樣就會確定數據來源,從而很大程度上提高了傳輸的安全性.子協議是基于客戶端和服務端共同實現的,客戶端主要功能有規定子協議標識、規定認證信息、加密傳輸數據.服務端主要功能有確認協議標識和認證信息、動態生成密鑰、接收解密數據.子協議系統整體結構如圖3所示:

圖3 子協議系統整體架構圖
1) 首先在WebSocket 連接建立成功后,客戶端和服務器端會協商一個子協議Security-WebSocket在請求頭中作為Sec-WebSocket-Protocol字段的值.并且約定在3 s內客戶端需要發送身份標識信息給服務器,標識信息如下:
[″auth″, ″I am client″].
2) 當客戶端接收到服務端生成的密鑰后,根據aes-128-cbc加密算法加密數據[10],該算法有3個參數:第1個是需要加密的明文,第2個是密鑰,第3個是初始偏移向量IV,其中IV是每次動態生成的.下面是一個客戶端根據密鑰加密后將信息發送到服務器的例子:
[″data″,″pilpmplyf5wvvj31″,″EDpbyVNj676 IuS4nz8WbM88jjK3R_hXpax%2BywC748gQKtk XAg6HtrkcRm_5npucMyiuNgPR%2B8xPo0Zivt BPM7MV%2B4CR_ZWoAwCSLjYiGQZs%3D″].
3) 當客戶端加密完成后會攜帶認證信息和加密數據一起在3s內發送到服務端,每次傳輸過程都攜帶認證信息,目的是讓服務端知道發送方的來源,避免惡意攻擊.
1) 在建立連接時首先判斷子協議標識是否正確,若錯誤則直接斷開連接,在驗證子協議標識正確后會生成16 b的密鑰并且將其發送到客戶端,其數據格式如下:
[″secret″, ″HYJSHYDHXIDUYHDN″].
2) 發送完密鑰后在3 s內會接收到客戶端發送的加密數據,首先驗證認證信息,若認證信息驗證無誤,則使用協商的密鑰解密得到數據.
會話管理部分主要的功能是在用戶登錄成功后服務器自動創建session,服務器為每個用戶創建一個隨機生成的seesionid來標識是哪個用戶在發送信息,服務器和客戶端每次都是通過cookie完成seesionid的傳送,session在一定時間內有效,失效后服務器會銷毀之前的session并創建新的[11].當遇到跨站劫持漏洞時,黑客可能會竊取cookie偽造請求,本文作了2次身份驗證標識,這樣會在標識用戶身份時除了seesionid之外還有auth的值,雙重身份信息認證,很大程度上提高了通信的安全性.
本文使用typescript語言在本地完成WebSocket安全子協議系統的代碼實現,對該系統使用子協議和未使用子協議作對比測試,主要從連接請求認證、連接超時認證、數據加密結果、數據解密結果等方面作了測試.實驗結果是在軟件vscode 1.41中使用typescript語言,版本為v3.9編寫的,電腦硬件配置為:MacBook Pro (Retina, 13-inch, Early 2015) 、主頻為2.7 GHz 雙核Intel Core i5、內存為16 GB.
客戶端和服務端連接成功后Security-WebSocket子協議信息如圖4所示,其中Sec-WebSocket-Protocol”字段的值就是規定的子協議標識.

圖4 子協議標識
客戶端添加認證信息后和服務端正常通信過程如圖5所示.
當客戶端未按規定發送身份認證信息或未在3 s內成功發送數據,則服務器會中斷連接,為了不暴露更多的錯誤信息,服務器只會中斷連接但不返回錯誤信息.服務端對數據解密后的明文信息以及多次實驗后WebSocket協議和Security-WebSocket子協議建立連接和數據傳輸平均時間對比如圖6所示.

圖5 客戶端與服務器通信過程

圖6 2種協議性能對比結果
從上面的結果可以看出Security-WebSocket子協議從連接成功開始增加了雙重認證功能,每次在數據傳輸過程中都是攜帶認證信息并且加密傳輸,而且限定了傳輸時間,如果超時就會斷開連接.通過對子協議和WebSocket協議進行性能對比,可以發現在建立連接時子協議耗時比WebSocket協議多耗時1 ms,在數據傳輸時子協議比WebSocket協議會多耗時50 ms左右.雖然子協議耗時比WebSocket協議多一點,但它的安全性比WebSocket協議高了很多,而且Security-WebSocket子協議在一定程度上可以預防跨站劫持漏洞.
本文通過分析和研究WebSocket協議,了解到該協議不受同源策略的限制,這就可能會存在跨站劫持漏洞.針對該漏洞設計并使用typescript 語言實現了一個簡單的子協議系統,該子協議在通信時使用雙重身份認證以及數據加密技術來預防不法分子的惡意劫持并偽造假身份竊取數據.最后在性能測試方面通過對WebSocket協議和子協議傳輸時間對比發現子協議會耗時多一點,但是在可控范圍之內.Security-WebSocket可以很好地預防跨站劫持漏洞.
Security-WebSocket子協議還存在以下不足,該協議功能比較單一,只可以預防跨站劫持漏洞,還有許多其他漏洞都不能防御.在性能方面由于使用了雙重認證和數據加密,所以在提升安全性的同時傳輸速度受到了一定的影響,這些不足之處還有待改善.