首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

深入理解跨站点 WebSocket 劫持漏洞的原理及防范(1)

深入理解跨站点 WebSocket 劫持漏洞的原理及防范(1)

序言WebSocket 作为 HTML5 的新特性之一格外吸引着开发人员的注意,因为它的出现使得客户端(主要指浏览器)提供对 Socket 的支持成为可能,从而在客户端和服务器之间提供了一个基于单 TCP 连接的双向通道。对于实时性要求比较高的应用而言,譬如在线证券、在线游戏,以及不同设备之间信息同步。信息实时同步一直是技术难题,在 WebSocket 出现之前,常见解决方案一般就是轮询(Polling)和 Comet 技术,但这些技术增加了设计复杂度,也造成了网络和服务器的额外负担,在负载较大的情况下效率相对低下,导致应用的可伸缩行收到制约。对于此类应用的开发者来说,WebSocket 技术简直就是神兵利器,读者可以登陆 websocket.org 网站观看特色案例,以及它提供的 WebSocket 和 Comet 的性能对比分析报告。最近几年内 WebSocket 技术被开发人员广泛应用到各类实际应用中。不幸的是,WebSocket 相关的安全漏洞也逐步被披露出来,其中最容易发生的就是跨站点 WebSocket 劫持漏洞。本文将深入浅出为读者介绍跨站点 WebSocket 漏洞的原理、检测方法和修复方法,希望能帮助广大读者在实际工作中避免这个已知安全漏洞。
WebSocket 协议握手和安全保障为了便于阐述跨站点 WebSocket 劫持漏洞原理,本文将简单描述 WebSocket 协议的握手和切换过程。建议有兴趣的读者阅读参考文献中提供的 RRFC                                6455 规范,深入学习 WebSocket 协议。
了解过 WebSocket 技术的读者都知道 ws://和 http://,那么 WebSocket 和 HTTP 是什么关系呢。笔者对这个问题的理解是,WebSocket 是 HTML5 推出的新协议,跟 HTTP 协议内容本身没有关系。WebSocket 是持久化的协议,而 HTTP 是非持久连接。正如前文所述,WebSocket 提供了全双工沟通,俗称 Web 的 TCP 连接,但 TCP 通常处理字节流(跟消息无关),而 WebSocket 基于 TCP 实现了消息流。WebSocket 也类似于 TCP 一样进行握手连接,跟 TCP 不同的是,WebSocket 是基于 HTTP 协议进行的握手。笔者利用 Chrome 开发者工具,收集了 websocket.org 网站的 Echo 测试服务的协议握手请求和响应,如清单 1 和 2 所示。
清单                                        1. WebSocket 协议升级请求
1
2
3
4
5
6
7
8
9
10
11
12
13
14
GET ws://echo.websocket.org/?encoding=text HTTP/1.1
Host: echo.websocket.org
Connection: Upgrade
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket
Origin: http://www.websocket.org
Sec-WebSocket-Version: 13
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) Chrome/49.0.2623.110
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8,zh-CN;q=0.6
Cookie: _gat=1; _ga=GA1.2.2904372.1459647651; JSESSIONID=1A9431CF043F851E0356F5837845B2EC
Sec-WebSocket-Key: 7ARps0AjsHN8bx5dCI1KKQ==
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits




熟悉 HTTP 的朋友可以发现 WebSocket 的核心了,对的,这就是 Connection:Upgrade 和 Upgrade:websocket 两行。这两行相当于告诉服务器端:我要申请切换到 WebSocket 协议。
清单                                        2. WebSocket 协议升级响应
1
2
3
4
5
6
7
8
9
10
11
12
13
HTTP/1.1 101 Web Socket Protocol Handshake
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: content-type
Access-Control-Allow-Headers: authorization
Access-Control-Allow-Headers: x-websocket-extensions
Access-Control-Allow-Headers: x-websocket-version
Access-Control-Allow-Headers: x-websocket-protocol
Access-Control-Allow-Origin: http://www.websocket.org
Connection: Upgrade
Date: Sun, 03 Apr 2016 03:09:21 GMT
Sec-WebSocket-Accept: wW9Bl95VtfJDbpHdfivy7csOaDo=
Server: Kaazing Gateway
Upgrade: websocket




一旦服务器端返回 101 响应,即可完成 WebSocket 协议切换。服务器端即可以基于相同端口,将通信协议从 http://或 https://切换到 ws://或 wss://。协议切换完成后,浏览器和服务器端即可以使用 WebSocket                                API 互相发送和收取文本和二进制消息。
这里要解释一些安全相关的重要头部参数,Sec-WebSocket-Key 和 Sec-WebSocket-Accept。这涉及一个 WebSocket 安全特性,客户端负责生成一个 Base64 编码过的随机数字作为 Sec-WebSocket-Key,服务器则会将一个 GUID 和这个客户端的随机数一起生成一个散列 Key 作为 Sec-WebSocket-Accept 返回给客户端。这个工作机制可以用来避免缓存代理(caching                                proxy),也可以用来避免请求重播(request replay)。
细心的读者可能也注意到很多其他“Sec-”开头的 WebSocket 相关的 Header。这其实也是 WebSocket 设计者为了安全的特意设计,以“Sec-”开头的 Header 可以避免被浏览器脚本读取到,这样攻击者就不能利用 XMLHttpRequest 伪造 WebSocket 请求来执行跨协议攻击,因为 XMLHttpRequest 接口不允许设置 Sec-开头的 Header。
返回列表