Description
The WebSocket specification - developed as part of the HTML5 initiative - introduced the WebSocket JavaScript interface, which defines a full-duplex single socket connection over which messages can be sent between client and server. In order to create a Websocket channel, the browser - via JavaScript - sends to the webserver a specific request, like the following:
GET / HTTP/1.1
Host: XXXXX:8004
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:38.0) Gecko/20100101 Firefox/38.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Sec-WebSocket-Version: 13
Origin: XXXXXX:8003
Sec-WebSocket-Extensions: permessage-deflate
Sec-WebSocket-Key: jecleCYu+zulEtNfWPDUHQ==
Authorization: Basic [...]
Connection: keep-alive, Upgrade
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket
If the server accepts the request of upgrading the connection to a websocket channel, it will send back a http response with status code 101, like the following:
HTTP/1.1 101 Switching Protocols
Upgrade: Websocket
Server: Microsoft-IIS/8.5
x-ms-hdi-servedby: GATEWAY0
x-ms-hdi-active: headnode1.XXXX.net
x-ms-leader-detect-time: 0
X-Powered-By: ARR/2.5
Sec-WebSocket-Accept: dsFIbttEBYGLWHitOKbGhmXyzeI=
Connection: Upgrade
X-Powered-By: ASP.NET
X-Content-Type-Options: nosniff
Date: Tue, 09 Jun 2015 19:43:59 GMT
Because Websockets are not restrained by the same-origin policy, an attacker can easily initiate a Websocket request from a malicious webpage targeting the ws:// or wss:// endpoint URL of the attacked application. According to the RFC 6455, the Websocket server can use any client authentication mechanism available to a generic HTTP server, such as cookies, HTTP authentication or TLS authentication. Because of that, the browser sends the authentication information along with the Websocket handshake/upgrade request, similar to a Cross-Site Request Forgery (CSRF), but in the Websocket scenario this attack can be extended from a write-only CSRF attack to a full read/write communication with a Websocket service.
One way to secure the Websocket server is to check the Origin http request header, which is automatically included by the browser and cannot be controlled by client-side code. According to our analysis, Zeppelin does not perform any check on the Origin header, allowing arbitrary Cross-Origin requests.
This means that an attacker could create a malicious website containing a malicious javascript code and force the victim user to open it (e.g., by sending an email). Once the client-side code is acquired and executed by the victim's browser, the attacker could control the websocket channel and, then, execute arbitrary code on the Spark cluster via Zeppelin.
Recommendations:
It is strongly recommended to apply a patch to the current Zeppelin version in order to check, at least, the Origin header.