赵娟娟 刘昌华
(武汉轻工大学数学与计算机学院 武汉 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子协议还存在以下不足,该协议功能比较单一,只可以预防跨站劫持漏洞,还有许多其他漏洞都不能防御.在性能方面由于使用了双重认证和数据加密,所以在提升安全性的同时传输速度受到了一定的影响,这些不足之处还有待改善.