多用户的春天WebSocket安全问题,怎么解决
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多用户的春天WebSocket安全问题,怎么解决相关的知识,希望对你有一定的参考价值。
参考技术AWebSocket是html5开始提供的一种浏览器与服务器间进行全双工通讯的网络技术。WebSocket通信协议于2011年被IETF定为标准RFC 6455,WebSocket API也被W3C定为标准,主流的浏览器都已经支持WebSocket通信。
WebSocket协议是基于TCP协议上的独立的通信协议,在建立WebSocket通信连接前,需要使用HTTP协议进行握手,从HTTP连接升级为WebSocket连接。浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。
WebSocket定义了两种URI格式, “ws://“和“wss://”,类似于HTTP和HTTPS, “ws://“使用明文传输,默认端口为80,”wss://“使用TLS加密传输,默认端口为443。
ws-URI: "ws://host[:port]path[?query]" wss-URI: "wss://host[:port]path[?query]"
WebSocket 握手阶段,需要用到一些HTTP头,升级HTTP连接为WebSocket连接如下表所示。
一次完整的握手连接如下图:
一旦服务器端返回 101 响应,即可完成 WebSocket 协议切换。服务器端可以基于相同端口,将通信协议从 http://或 https:// 切换到 ws://或 wss://。协议切换完成后,浏览器和服务器端可以使用 WebSocket API 互相发送和收取文本和二进制消息。
WebSocket应用安全问题
WebSocket作为一种通信协议引入到Web应用中,并不会解决Web应用中存在的安全问题,因此WebSocket应用的安全实现是由开发者或服务端负责。这就要求开发者了解WebSocket应用潜在的安全风险,以及如何做到安全开发规避这些安全问题。
认证
WebSocket 协议没有规定服务器在握手阶段应该如何认证客户端身份。服务器可以采用任何 HTTP 服务器的客户端身份认证机制,如 cookie认证,HTTP 基础认证,TLS 身份认证等。在WebSocket应用认证实现上面临的安全问题和传统的Web应用认证是相同的,如: CVE-2015-0201 , Spring框架的Java SockJS客户端生成可预测的会话ID,攻击者可利用该漏洞向其他会话发送消息; CVE-2015-1482 , Ansible Tower未对用户身份进行认证,远程攻击者通过websocket连接获取敏感信息。
授权
同认证一样,WebSocket协议没有指定任何授权方式,应用程序中用户资源访问等的授权策略由服务端或开发者实现。WebSocket应用也会存在和传统Web应用相同的安全风险,如:垂直权限提升和水平权限提升。
跨域请求
WebSocket使用基于源的安全模型,在发起WebSocket握手请求时,浏览器会在请求中添加一个名为Origin的HTTP头,Oringin字段表示发起请求的源,以此来防止未经授权的跨站点访问请求。WebSocket 的客户端不仅仅局限于浏览器,因此 WebSocket 规范没有强制规定握手阶段的 Origin 头是必需的,并且WebSocket不受浏览器同源策略的限制。如果服务端没有针对Origin头部进行验证可能会导致跨站点WebSocket劫持攻击。该漏洞最早在 2013 年被Christian Schneider 发现并公开,Christian 将之命名为跨站点 WebSocket 劫持 (Cross Site WebSocket Hijacking)(CSWSH)。跨站点 WebSocket 劫持危害大,但容易被开发人员忽视。相关案例可以参考: IPython Notebook( CVE-2014-3429 ), OpenStack Compute( CVE-2015-0259 ), Zeppelin WebSocket服务器 等跨站WebSocket劫持。
上图展示了跨站WebSocket劫持的过程,某个用户已经登录了WebSocket应用程序,如果他被诱骗访问了某个恶意网页,而恶意网页中植入了一段js代码,自动发起 WebSocket 握手请求跟目标应用建立 WebSocket 连接。注意到,Origin 和 Sec-WebSocket-Key 都是由浏览器自动生成的,浏览器再次发起请求访问目标服务器会自动带上Cookie 等身份认证参数。如果服务器端没有检查 Origin头,则该请求会成功握手切换到 WebSocket 协议,恶意网页就可以成功绕过身份认证连接到 WebSocket 服务器,进而窃取到服务器端发来的信息,或者发送伪造信息到服务器端篡改服务器端数据。与传统跨站请求伪造(CSRF)攻击相比,CSRF 主要是通过恶意网页悄悄发起数据修改请求,而跨站 WebSocket 伪造攻击不仅可以修改服务器数据,还可以控制整个双向通信通道。也正是因为这个原因,Christian 将这个漏洞命名为劫持(Hijacking),而不是请求伪造(Request Forgery)。
理解了跨站WebSocket劫持攻击的原理和过程,那么如何防范这种攻击呢?处理也比较简单,在服务器端的代码中增加 对Origin头的检查,如果客户端发来的 Origin 信息来自不同域,服务器端可以拒绝该请求。但是仅仅检查 Origin 仍然是不够安全的,恶意网页可以伪造Origin头信息,绕过服务端对Origin头的检查,更完善的解决方案可以借鉴CSRF的解决方案-令牌机制。
拒绝服务
WebSocket设计为面向连接的协议,可被利用引起客户端和服务器端拒绝服务攻击,相关案例可参考: F5 BIG-IP远程拒绝服务漏洞( CVE-2016-9253 )。
1. 客户端拒绝服务
WebSocket连接限制不同于HTTP连接限制,和HTTP相比,WebSocket有一个更高的连接限制,不同的浏览器有自己特定的最大连接数,如:火狐浏览器默认最大连接数为200。通过发送恶意内容,用尽允许的所有Websocket连接耗尽浏览器资源,引起拒绝服务。
2. 服务器端拒绝服务
WebSocket建立的是持久连接,只有客户端或服务端其中一发提出关闭连接的请求,WebSocket连接才关闭,因此攻击者可以向服务器发起大量的申请建立WebSocket连接的请求,建立持久连接,耗尽服务器资源,引发拒绝服务。针对这种攻,可以通过设置单IP可建立连接的最大连接数的方式防范。攻击者还可以通过发送一个单一的庞大的数据帧(如, 2^16),或者发送一个长流的分片消息的小帧,来耗尽服务器的内存,引发拒绝服务攻击, 针对这种攻击,通过限制帧大小和多个帧重组后的总消息大小的方式防范。
中间人攻击
WebSocket使用HTTP或HTTPS协议进行握手请求,在使用HTTP协议的情况下,若存在中间人可以嗅探HTTP流量,那么中间人可以获取并篡改WebSocket握手请求,通过伪造客户端信息与服务器建立WebSocket连接,如下图所示。防范这种攻击,需要在加密信道上建立WebSocket连接,使用HTTPS协议发起握手请求。
输入校验
WebSocket应用和传统Web应用一样,都需要对输入进行校验,来防范来客户端的XSS攻击,服务端的SQL注入,代码注入等攻击。
java 程序中怎么保证多线程的运行安全?
2.1.读一致性
Java 中针对上述“读不安全”的问题提供了关键字 volatile 来解决问题,被 volatile 修饰的成员变量,在内容发生更改的时候,会通知所有线程去主内存更新最新的值,这样就解决了读不安全的问题,实现了读一致性。
但是,读一致性是无法解决写一致性的,虽然能够使得每个线程都能及时获取到最新的值,但是1.1中的写一致性问题还是会存在。
既然如此,Java 为啥还要提供 volatile 关键字呢?这并非多余的存在,在某些场景下只需要读一致性的话,这个关键字就能够满足需求而且性能相对还不错,因为其他的能够保证“读写”都一直的办法,多多少少存在一些牺牲。
2.2.写一致性
Java 提供了三种方式来保证读写一致性,分别是互斥锁、自旋锁、线程隔离。
2.2.1.互斥锁
互斥锁只是一个锁概念,在其他场景也叫做独占锁、悲观锁等,其实就是一个意思。它是指线程之间是互斥的,某一个线程获取了某个资源的锁,那么其他线程就只能睡眠等待。
在 Java 中互斥锁的实现一般叫做同步线程锁,关键字 synchronized,它锁住的范围是它修饰的作用域,锁住的对象是:当前对象(对象锁)或类的全部对象(类锁)——锁释放前,其他线程必将阻塞,保证锁住范围内的操作是原子性的,而且读取的数据不存在一致性问题。
对象锁:当它修饰方法、代码块时,将会锁住当前对象
类锁:修饰类、静态方法时,则是锁住类的所有对象
注意: 锁住的永远是对象,锁住的范围永远是 synchronized 关键字后面的花括号划定的代码域。
2.2.2.自旋锁
自旋锁也只是一个锁概念,在其他场景也叫做乐观锁等。
自旋锁本质上是不加锁,而是通过对比旧数据来决定是否更新:
线程的安全性问题体现在:
原子性:一个或者多个操作在 CPU 执行的过程中不被中断的特性
可见性:一个线程对共享变量的修改,另外一个线程能够立刻看到
有序性:程序执行的顺序按照代码的先后顺序执行
导致原因:
缓存导致的可见性问题
线程切换带来的原子性问题
编译优化带来的有序性问题
解决办法:
JDK Atomic开头的原子类、synchronized、LOCK,可以解决原子性问题
synchronized、volatile、LOCK,可以解决可见性问题
Happens-Before 规则可以解决有序性问题
2.使用自动锁 synchronized。
3.使用手动锁 Lock。
4.保证一个或者多个操作在CPU执行的过程中不被中断。 参考技术C 使用synchronied关键字,可以用于代码块,方法(静态方法,同步锁是当前字节码对象;实例方法,同步锁是实例对象) 使用volatile 关键词 参考技术D 1.使用安全类,比如 Java. util. concurrent 下的类。
2.使用自动锁 synchronized。
3.使用手动锁 Lock。
以上是关于多用户的春天WebSocket安全问题,怎么解决的主要内容,如果未能解决你的问题,请参考以下文章
不会吧,你连Java 多线程线程安全都还没搞明白,难怪你面试总不过
wingdow xp iis 安装好后,在浏览器上打入"http://localhost/"后,怎么要输入用户名和密码,怎么解决啊?