https网络通信协议socket在有漏洞的操作系统使用安全吗?

WebSocket 作为 HTML5 的新特性之一格外吸引着开發人员的注意因为它的出现使得客户端(主要指浏览器)提供对 Socket 的支持成为可能,从而在客户端和服务器之间提供了一个基于单 TCP 连接的雙向通道对于实时性要求比较高的应用而言,譬如在线证券、在线游戏以及不同设备之间信息同步。信息实时同步一直是技术难题茬 WebSocket 出现之前,常见解决方案一般就是轮询(Polling)和 Comet 技术但这些技术增加了设计复杂度,也造成了网络和服务器的额外负担在负载较大的凊况下效率相对低下,导致应用的可伸缩行收到制约对于此类应用的开发者来说,WebSocket 技术简直就是神兵利器读者可以登陆

带来的新特性の一。但是很不幸跨域资源共享不适应于 WebSocket,WebSocket 没有明确规定跨域处理的方法

明白跨站点 WebSocket 劫持漏洞原理后,大家就很容易联想到这个漏洞嘚检测方法了重点就在于重播 WebSocket 网络通信协议socket升级请求。简单来说就是使用能拦截到 WebSocket 握手请求的工具修改请求中的 Origin 头信息,然后重新发送这个请求看看服务器是否能够成功返回 101 响应。如果连接失败那么说明这个 WebSocket 是安全的,因为它可以正确拒绝来自不同源(Origin)的连接请求如果连接成功,通常就已经证明服务器端没有执行源检查为了严谨起见,最好进一步测试是否可以发送 WebSocket 消息如果这个 WebSocket 连接能够发送/接受消息的话,则完全证明跨站点 WebSocket 劫持漏洞的存在

为了便于演示如何测试及修复这个漏洞,笔者编写了一个简单的 WebSocket 应用这个应用基於 JAAS 实现了 HTTP BASIC 身份认证,读者可以将这个程序下载部署到 Tomcat 中进行测试打开客户端网页后首先进行登录,然后点击“连接”按钮通过 JavaScript 建立 WebSocket 连接然后点击“发送”按钮提交一个问题到服务器端,服务器端实时确认收到查询请求5 秒后再将结果推送给客户端。

测试工具方面有很多選择由于许可证原因,笔者采用了开源的 OWASP ZAP v2.4.3这里要简单说一下,测试过程主要基于测试工具的代理拦截到 WebSocket 握手请求以及 WebSocket 消息通信,然後通过工具修改 Origin 后重发请求如果连接成功后,重发 WebSocket 客户端消息以上功能各个商业安全测试工具都可以做到。

2. 右键选择重发 WebSocket 网络通信协議socket升级请求将其中的 Origin 修改为任意其他网址后点击发送。

3. 点击响应标签可以看到服务器端返回了 101,即网络通信协议socket握手成功

4. 进一步测試 WebSocket 消息是否可以重发。如下图所示右键点击第一条客户端发出的 WebSocket 消息,选择重发输入测试消息”www”后点击发送,可以看到 ZAP 陆续收到两條服务器返回的消息这充分证明被测试应用站点存在跨站点 WebSocket 劫持漏洞。

前文介绍了跨站点 WebSocket 劫持漏洞原理和检测相信读者已经明白它的危害,接下来我们谈谈如何防范这个漏洞这个漏洞的原理听起来略微复杂,但幸运的是测试起来相对比较简单那么修复会不会也很简單。很多读者会想到不就是在服务器代码中检查 Origin 参数嘛。是的检查 Origin 很有必要,但不充分笔者推荐大家要在服务器端的代码中增加 Origin 检查,如果客户端发来的 Origin 信息来自不同域建议服务器端拒绝这个请求,发回 403 错误响应拒绝连接

笔者采用了 Java EE 技术编写的 WebSocket 测试应用,Java EE 的 WebSocket API 中提供了配置器允许开发人员重写配置用来拦截检查网络通信协议socket握手过程笔者在文章附录的源代码中已经包含了这部分代码,下面简单介紹一些核心类和配置如果对 Java EE WebSocket API 不太熟悉的读者,建议可以先查阅相关规范

1. 首先编写一个 WebSocket 服务器终端的配置器,如清单 4 所示继承并重写 checkOrigin 方法注意,笔者忽略了没有 Origin 的场景这一点要视各个应用的实际情况而定,如果有非浏览器客户端的话则需要加上这一个检查。同时建議非浏览器客户端参见下文的令牌机制

2. 然后将该配置器关联到 WebSocket 服务器代码中。

有兴趣的读者可以自己尝试如果补上以上代码后,重播篡改的 WebSocket 握手网络通信协议socket请求会收到 403 错误

以上看起来很美好,但是仅仅检查 Origin 远远不够别忘记了,如果 WebSocket 的客户端不是浏览器非浏览器嘚客户端发来的请求根本就没有 Origin。除此之外我们要记得,恶意网页是可以伪造 Origin 头信息的更彻底的解决方案还是要借鉴 CSRF 的解决方案-令牌机制。

鉴于篇幅原因笔者就不详细贴出整个设计和代码,建议读者参照以下概要设计提高 WebSocket 应用的安全

3. 服务器端验证 Token 是否正确,一旦囸确则将这个 Token 标示为废弃不再重用同时确认 WebSocket 握手连接成功;如果 Token 验证失败或者身份认证失败,则返回 403 错误

这个方案里的 Token 设计是关键,筆者推荐的方案是为登录用户生成一个 Secure Random 存储在 Session 中然后利用对称加密(譬如 AES GCM)加密这个 Secure Random 值作为令牌,将加密后的令牌发送给客户端用来进荇连接这样每个 Session 有一个唯一的随机数,每个随机数可以通过对称加密生成若干份一次性令牌用户即便通过不同终端通过 WebSocket 连接到服务器,服务器可以在保障令牌唯一且一次性使用的前提下依然能将不同通道中的信息关联到同一用户中。

可能存在另外一个设计思路在 WebSocket 消息中增加令牌和身份信息,但笔者觉得这样的设计有悖于 WebSocket 的设计思想而且增加了不必要的网络负载。抛砖引玉欢迎读者提供更好的设計方案。

本文笔者跟读者分享了对 WebSocket 网络通信协议socket握手的理解并在此基础上阐述了跨站点 WebSocket 劫持漏洞的原理。正如文中所提已知的各类 WebSocket 漏洞中,只有这个是广泛存在于 Web 应用代码中的漏洞笔者同时分享了检测跨站点 WebSocket 劫持漏洞的方法,并且基于 Java EE 技术介绍了漏洞的修复办法以忣更全面的基于令牌机制的安全解决方案。

}

WebSocket网络通信协议socket是基于TCP网络通信协議socket上的独立的通信网络通信协议socket在建立WebSocket通信连接前,需要使用HTTP网络通信协议socket进行握手从HTTP连接升级为WebSocket连接。浏览器和服务器只需要完成┅次握手两者之间就直接可以创建持久性的连接,并进行双向数据传输

一次完整的握手连接如下图:

一旦服务器端返回 101 响应,即可完成 WebSocket 網络通信协议socket切换服务器端可以基于相同端口,将通信网络通信协议socket从 http://或 https:// 切换到 ws://或 wss://网络通信协议socket切换完成后,浏览器和服务器端可以使用 WebSocket API 互相发送和收取文本和二进制消息

WebSocket作为一种通信网络通信协议socket引入到Web应用中,并不会解决Web应用中存在的安全问题因此WebSocket应用的安全實现是由开发者或服务端负责。这就要求开发者了解WebSocket应用潜在的安全风险以及如何做到安全开发规避这些安全问题。

WebSocket 网络通信协议socket没有規定服务器在握手阶段应该如何认证客户端身份服务器可以采用任何 HTTP 服务器的客户端身份认证机制,如 cookie认证HTTP 基础认证,TLS 身份认证等茬WebSocket应用认证实现上面临的安全问题和传统的Web应用认证是相同的,如: CVE- , Spring框架的Java SockJS客户端生成可预测的会话ID攻击者可利用该漏洞向其他会话发送消息; CVE- , Ansible Tower未对用户身份进行认证,远程攻击者通过websocket连接获取敏感信息

同认证一样,WebSocket网络通信协议socket没有指定任何授权方式应用程序中用户資源访问等的授权策略由服务端或开发者实现。WebSocket应用也会存在和传统Web应用相同的安全风险如:垂直权限提升和水平权限提升。

WebSocket使用基于源的安全模型在发起WebSocket握手请求时,浏览器会在请求中添加一个名为Origin的HTTP头Oringin字段表示发起请求的源,以此来防止未经授权的跨站点访问请求WebSocket 的客户端不仅仅局限于浏览器,因此 WebSocket 规范没有强制规定握手阶段的 Origin

上图展示了跨站WebSocket劫持的过程某个用户已经登录了WebSocket应用程序,如果怹被诱骗访问了某个恶意网页而恶意网页中植入了一段js代码,自动发起 WebSocket 握手请求跟目标应用建立 WebSocket 连接注意到,Origin 和 Sec-WebSocket-Key 都是由浏览器自动生荿的浏览器再次发起请求访问目标服务器会自动带上Cookie 等身份认证参数。如果服务器端没有检查 Origin头则该请求会成功握手切换到 WebSocket 网络通信協议socket,恶意网页就可以成功绕过身份认证连接到 WebSocket 服务器进而窃取到服务器端发来的信息,或者发送伪造信息到服务器端篡改服务器端数據与传统跨站请求伪造(CSRF)攻击相比,CSRF 主要是通过恶意网页悄悄发起数据修改请求而跨站 WebSocket 伪造攻击不仅可以修改服务器数据,还可以控制整个双向通信通道也正是因为这个原因,Christian 将这个漏洞命名为劫持(Hijacking)而不是请求伪造(Request Forgery)。

理解了跨站WebSocket劫持攻击的原理和过程那么如何防范這种攻击呢?处理也比较简单,在服务器端的代码中增加 对Origin头的检查如果客户端发来的 Origin 信息来自不同域,服务器端可以拒绝该请求但是僅仅检查 Origin 仍然是不够安全的,恶意网页可以伪造Origin头信息绕过服务端对Origin头的检查,更完善的解决方案可以借鉴CSRF的解决方案-令牌机制

WebSocket设计為面向连接的网络通信协议socket,可被利用引起客户端和服务器端拒绝服务攻击相关案例可参考: F5 BIG-IP远程拒绝服务漏洞( CVE- )。

WebSocket连接限制不同于HTTP连接限淛和HTTP相比,WebSocket有一个更高的连接限制不同的浏览器有自己特定的最大连接数,如:火狐浏览器默认最大连接数为200。通过发送恶意内容用盡允许的所有Websocket连接耗尽浏览器资源,引起拒绝服务

2. 服务器端拒绝服务

WebSocket建立的是持久连接,只有客户端或服务端其中一发提出关闭连接的請求WebSocket连接才关闭,因此攻击者可以向服务器发起大量的申请建立WebSocket连接的请求建立持久连接,耗尽服务器资源引发拒绝服务。针对这種攻可以通过设置单IP可建立连接的最大连接数的方式防范。攻击者还可以通过发送一个单一的庞大的数据帧(如, 2^16)或者发送一个长流的分爿消息的小帧,来耗尽服务器的内存引发拒绝服务攻击, 针对这种攻击,通过限制帧大小和多个帧重组后的总消息大小的方式防范

WebSocket使用HTTP戓HTTPS网络通信协议socket进行握手请求,在使用HTTP网络通信协议socket的情况下若存在中间人可以嗅探HTTP流量,那么中间人可以获取并篡改WebSocket握手请求通过偽造客户端信息与服务器建立WebSocket连接,如下图所示防范这种攻击,需要在加密信道上建立WebSocket连接使用HTTPS网络通信协议socket发起握手请求。

WebSocket应用和傳统Web应用一样都需要对输入进行校验,来防范来客户端的XSS攻击服务端的SQL注入,代码注入等攻击

Websocket是一个基于TCP的HTML5的新网络通信协议socket,可鉯实现浏览器和服务器之间的全双工通讯在即时通讯等应用中,WebSocket具有很大的性能优势, 并且非常适合全双工通信但是,和任何其他技术┅样开发WebSocket应用也需要考虑潜在的安全风险。


}

开始之前先热热身,讲个小故倳:

年终奖下来了张大胖琢磨着去买点儿股票作为投资,他用浏览器访问了 输入了用户名和密码,登录成功

发起Http请求,浏览器都会兢兢业业地把Cookie加入到Http请求的Header中一并发到就知道张大胖已经登陆过了,就可以按照张大胖的请求来做事情比如查看股票,买卖股票

张夶胖看到股票涨幅不错,心中暗喜 他又打开了, 去看一些自己的小秘密

浏览器把发起了HTTP请求 !

浏览器严格按照规定,把之前存储的cookie也添加到Http请求中 !

无辜的的JavaScript发出的还是张大胖发出的。

的时候(不管是人点击按钮/链接或者是通过程序的方式),存储在浏览器的下载嘚JS利用XMLHttp访问了的JavaScript去访问 浏览器又收到了cookie并且保存了下来, 这一次张大胖发现发起了一个HTTP请求 这个请求希望把HTTP 网络通信协议socket升级为web socket网络通信协议socket,下面是HTTP请求的Header:

注意Cookie数据也发送给了检查Cookie,确认是个登陆过的客户于是建立websocket连接,并且推送张大胖订阅的最新的股票信息

张大胖看到最新的股票信息,很高兴他又打开了, 去看一些自己的小秘密

这个发起HTTP请求,也要建立websocket连接

, 于是张大胖的信息就暴漏了 

如果这个websocket还支持别的操作,那危害就更大了(这也是被称为“劫持”,而不仅仅是“伪造”的原因)

可以看出websocket不遵守同源策略,是导致跨站点脚本劫持的最大原因

Websocket网络通信协议socket怎么解决这个问题呢?

敏锐的同学已经注意了在前面的HTTP请求中,有个叫做Origin的东西:

所以在的服务器端在建立websocket连接的时候,一定要去检查这个Origin,确保这个Origin在自己的白名单中

1. 不就是一个Origin吗? 黑客可以轻松地伪造啊

注意:這一切都发生在张大胖的浏览器中,是张大胖在操作 黑客想伪造的话,只能通过JavaScript来修改它

但是HTTP网络通信协议socket规定: 这个Origin是在HTTP Header中, 是由瀏览器自动加上的不能通过编程的方式(如JavaScript)来改变它

2. 那黑客可以修改HTTP请求把这个Origin改了啊?

如果你控制了张大胖的浏览器甚至张夶胖的电脑,那肯定可以修改HTTP请求 但是都控制电脑了,一切尽在掌握还费这劲干嘛,直接监控用户名和密码不就得了

如果你充当中間人,通过抓包的方式来修改Origin,那确实可以这时候张大胖需要用Https,和wss来防范了

3. 还有没有别的办法来防范?

有的还有个更加安全的辦法,和防范CSRF的思想是一致的: 使用token

(1) 服务器端给每个websocket客户端分配一个随机的,唯一的token

(3) 服务器端验证token 如果有效,才建立连接并且废弃掉这个token。

}

我要回帖

更多关于 网络通信协议socket 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信