什么是Websocket?
- Websocket是一種通信協議
- 通過HTTP發起的,全雙工
- 用於現代Web應用程序,流式傳輸數據
Websocket和HTTP區別
- HTTP作為老牌協議,客戶端發送請求報文,服務器回復響應報文。通常,響應立即發生,表示事物完成。即使網絡保持打開狀態,也將用於請求和響應的單獨事物
- WebSocket通過HTTP發起,並且是長期存在的,消息隨時可以向另一方發送,本質上不具有事務性,所以存在空閑狀態。此外,Websocket對於需求低延遲服務的消息情況下十分討喜,比如金融數據實時傳輸
Websocket如何建立
Websocket通常使用客戶端JavaScript腳本創建
var ws = new WebSocket("wss://normal-website.com/chat");
和HTTP一樣,存在加密證書:ws協議屬於未加密連接,wss協議屬於加密連接。
為了建立連接,瀏覽器和服務器會通過HTTP執行WebSocket握手,瀏覽器發送一個握手請求:
GET /chat HTTP/1.1
Host: normal-website.com
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: wDqumtseNBJdhkihL6PW7w==
Connection: keep-alive, Upgrade
Cookie: session=KOsEJNuflw4Rd9BDNrVmvwBF9rEijeE2
Upgrade: websocket
服務器返回一個WebStock握手響應:
HTTP/1.1 101 Switching Protocols
Connection: Upgrade
Upgrade: websocket
Sec-WebSocket-Accept: 0FFP+2nmNIf/h+4BP36k9uzrYGk=
此時,網絡連接保持打開狀態,可用於向任一方向發送 WebSocket 消息。
注意
WebSocket 握手消息的幾個特性值得注意:
- 請求和響應中 的Connection和Upgrade標頭表明這是一次 WebSocket 握手。
- Sec-WebSocket-Version請求頭指定WebSocket協議版本的客戶端希望使用。通常是13.
- Sec-WebSocket-Key請求報頭包含Base64編碼的隨機值,這應該在每個握手請求是隨機產生的。
- Sec-WebSocket-Accept響應報頭包含在提交的值的散列Sec-WebSocket-Key請求頭,具有在協議規范中定義的特定的字符串串聯。這樣做是為了防止錯誤配置的服務器或緩存代理導致誤導性響應。
WebSocket消息是怎樣的?
一旦建立了 WebSocket 連接,客戶端或服務器就可以在任一方向上異步發送消息。
可以使用客戶端 JavaScript 從瀏覽器發送一條簡單的消息,如下所示:
ws.send("Peter Wiener");
原則上,WebSocket 消息可以包含任何內容或數據格式。在現代應用程序中,通常使用 JSON 在 WebSocket 消息中發送結構化數據。
例如,使用 WebSockets 的聊天機器人應用程序可能會發送如下消息:
`
{"user":"Hal Pline","content":"I wanted to be a Playstation growing up, not a device to answer your inane questions"}
WebSocket安全漏洞
原則上,幾乎所有 Web 安全漏洞都可能與 WebSockets 相關:
- 傳輸到服務器的用戶提供的輸入可能會以不安全的方式進行處理,從而導致諸如SQL 注入或 XML 外部實體注入等漏洞。
- 一些通過 WebSockets 達到的盲漏洞可能只能使用帶外 (OAST) 技術檢測到。
- 如果攻擊者控制的數據通過 WebSockets 傳輸到其他應用程序用戶,則可能導致XSS或其他客戶端漏洞。
操作WebSocket消息利用漏洞
操縱 WebSocket 消息以利用漏洞
大多數影響 WebSocket 的基於輸入的漏洞都可以通過篡改 WebSocket 消息的內容來發現和利用。
例如,假設聊天應用程序使用 WebSockets 在瀏覽器和服務器之間發送聊天消息。當用戶輸入聊天消息時,會向服務器發送如下所示的 WebSocket 消息:
{"message":"Hello Carlos"}
消息的內容(再次通過 WebSockets)傳輸到另一個聊天用戶,並在用戶的瀏覽器中呈現如下:
<td>Hello Carlos</td>
在這種情況下,如果沒有其他輸入處理或防御在起作用,攻擊者可以通過提交以下 WebSocket 消息來執行概念驗證 XSS 攻擊:
{"message":"<img src=1 onerror='alert(1)'>"}
操縱 WebSocket 握手利用漏洞
某些 WebSockets 漏洞只能通過操縱 WebSocket 握手來發現和利用。這些漏洞往往涉及設計缺陷,例如:
- 錯誤地信任 HTTP 標頭以執行安全決策,例如X-Forwarded-For標頭。
- 會話處理機制中的缺陷,因為處理 WebSocket 消息的會話上下文通常由握手消息的會話上下文決定。
- 由應用程序使用的自定義 HTTP 標頭引入的攻擊面。
使用跨站 WebSockets 來利用漏洞
當攻擊者從攻擊者控制的網站進行跨域 WebSocket 連接時,就會出現一些 WebSockets 安全漏洞。這被稱為跨站點 WebSocket 劫持攻擊,它涉及利用WebSocket 握手中的跨站點請求偽造( CSRF ) 漏洞。這種攻擊通常會產生嚴重的影響,允許攻擊者代表受害用戶執行特權操作或捕獲受害用戶有權訪問的敏感數據。
如何保護 WebSocket 連接
為了最大限度地降低 WebSockets 產生的安全漏洞的風險,請使用以下准則:
- 使用wss://協議(基於 TLS 的 WebSockets)。
- 硬編碼 WebSockets 端點的 URL,當然不要將用戶可控的數據合並到這個 URL 中。
- 保護WebSocket握手消息免受CSRF攻擊,避免跨站WebSockets劫持漏洞。
- 將通過 WebSocket 接收的數據視為雙向不可信數據。在服務器端和客戶端安全地處理數據,以防止基於輸入的漏洞,例如 SQL 注入和跨站點腳本。