WebSockets meets Security

WebSockets are intended to build bi-directional connections between a webbrowser and a server. This must be done in a safe way. In addition, the WebSockets have a huge disadvantage (to say it politely).

WebSockets, the safe way

For WebSocket connections you must follow the same rules as for all network connections: the communication partners must be authenticated if necessary, and if the transmission contains sensitive data, the connection must be encrypted.

In case of Websockets, the client is authenticated by the server over the usual HTTP authentication mechanisms such as cookies, HTTP authentication or TLS authentication. For encryption you can use TLS (Transport Layer Security). While a conventional WebSocket connection is established via HTTP, a protected one uses HTTPS. The distinction is based on the URI schemes:

 

Normal connection: ws://{host}:{port}/{path to the server}

Secure connection: wss://{host}:{port}/{path to the server}

 

Regardless of the authentication and / or encryption of the data, the well-known principle “Never Trust the client” also applies to the WebSockets: All received data must be checked by the server, the client may be under the control of an attacker. Additional the server can verify in the ‘Origin’ header if a connection request originates from a desired domain. As usual with client-delivered data, an attacker can spoof this header.

Now let’s take a look on the disadvantage of WebSockets:

WebSockets and the Same Origin Policy

Some descriptions of the WebSocket API indicates that the Same Origin Policy applies to WebSocket connections. But is this really so, and should it be at all? Apparently there is some confusion.

The WebSocket protocol

In the standard for the WebSocket protocol, RFC 6455 [1], the abstract says: “The security model used for this is the origin-based security model Commonly used by web browsers.” And the following is part of the introduction, which is not relevant for the standard (non-normative):

“1.6. Security Model

_This section is non-normative._

The WebSocket Protocol uses the origin model used by web browsers to restrict which web pages can contact a WebSocket server when the WebSocket Protocol is used from a web page. Naturally, when the WebSocket Protocol is used by a dedicated client directly (i.e., not from a web page through a web browser), the origin model is not useful, as the client can provide any arbitrary origin string.”

Additional there is a reference to RFC 6454 [2], in which the Same Origin Policy is specified.

In the actual definition of the protocol it is defined that web browser must enclose a ‘Origin’ header while connecting, while this is optional for all other clients. In section 10, “Security Considerations“, is accordingly also noted that the ‘Origin’ header can only protect against attacks from malicious JavaScript code in a web browser (because the header is then sent by the browser and not from the JavaScript code ) and the server should assume that the ‘Origin’ header may be forged. Since independent WebSocket clients can send the header, too, its existence is not even an indication that the connection request comes from a web browser.

Interim conclusion 1

Although the web browser must send a ‘Origin’ header to the server, the Same Origin Policy is not applied. Otherwise the ‘Origin’ header would be obsolete, since the connection request would only be sent by the browser if it went to the Origin of the initiating JavaScript code.

The WebSocket API

Now let’s take a look at the definition of the WebSocket API [3]. In this there is no mention of the Same Origin Policy. If the Same Origin Policy applies, the API definition had to specify that WebSockets connections are only possible to the Origin of the JavaScript code, and an error message in case of a violation of the Same Origin Policy would be necessary. Which leads to the conclusion, that, by definition of the WebSocket API, the Same Origin Policy did not apply for WebSockets.

Interim conclusion 2

The definition of WebSocket API does not require the Same Origin Policy. On the contrary, everything suggests that it is not appliable. Even if this is not explicitly stated anywhere.

The practical usage

Finally let’s take a look on the practical use of the WebSocket API. The Attack and Defense Labs developed a JavaScript-based port scanner, JS-Recon [4], [5]. It uses the WebSockets API to connect to any IP address on the local network, which would violate the Same Origin Policy if it would apply.

Conclusion

This all leads to one conclusion: The application of the Same Origin Policy is neither required by the protocol itself nor by the API. And in practice it is not observed.

“WebSockets Considered harmful!”

As a result, JavaScript code can establish WebSocket connections to any servers. It is up to the server to respond appropriately to unwanted connection requests, if necessary.

This applies even if the JavaScript code in question is a malicious one and has been injected, for example, via a XSS vulnerability. In this case, the code could then connect to the attacker’s server (which would accept the connection request, of course) and give the attacker access to the victim’s browser. How this could work shows for example “Waldo” [6], a proof-of-concept of the Qualys Security Labs, which implements a backdoor.

So WebSockets effectively subvert the Same Origin Policy. Although JavaScript code can not access the content of other Origins, JavaScript code injected in a web page can connect to any (WebSocket) server. I’m pretty sure this is not what the inventors had in mind. At least not the inventors of the Same Origin Policy.

To make it worse there is no mitigation or protection against such a misuse, since the old Atari excuse applies here: “It’s not a bug, it’s a feature”. As proetection, you can only completely disable WebSockets in your web browser, if you do not need it (and can find instructions how to do it for your browser).

 

Bibliography

  1. RFC 6455 – The WebSocket Protocol: http://tools.ietf.org/html/rfc6455
  2. RFC 6454 – The Web Origin Concept: http://tools.ietf.org/html/rfc6454
  3. The WebSocket API: http://dev.w3.org/html5/websockets/
  4. Attack and Defense Labs: „JS-Recon, HTML5 based JavaScript Network Reconnaissance Tool“, Description: http://www.andlabs.org/tools/jsrecon/jsrecon.html
  5. JS-Recon – HTML5 based JavaScript Network Reconnaissance Tool: http://www.andlabs.org/tools/jsrecon.html
  6. Qualys Security Labs: The Tiny Mighty Waldo: https://community.qualys.com/blogs/securitylabs/2012/08/03/the-tiny-mighty-waldo

CTOvision Pro Special Technology Assessments

We produce special technology reviews continuously updated for CTOvision Pro members. Categories we cover include:

  • Analytical Tools - With a special focus on technologies that can make dramatic positive improvements for enterprise analysts.
  • Big Data - We cover the technologies that help organizations deal with massive quantities of data.
  • Cloud Computing - We curate information on the technologies enabling enterprise use of the cloud.
  • Communications - Advances in communications are revolutionizing how data gets moved.
  • GreenIT - A great and virtuous reason to modernize!
  • Infrastructure  - Modernizing Infrastructure can have dramatic benefits on functionality while reducing operating costs.
  • Mobile - This revolution is empowering the workforce in ways few of us ever dreamed of.
  • Security  -  There are real needs for enhancements to security systems.
  • Visualization  - Connecting computers with humans.
  • Hot Technologies - Firms we believe warrant special attention.

 

solid
About Carsten Eilers

Carsten Eilers is a freelance consultant and coach on IT security and technical data protection. His work focuses on the security of web applications, local networks and individual client computers. He is not only a regular contributor to German publications PHP Magazin and Entwickler Magazin, but also writes for other magazines and online media. He can be contacted at http://bit.ly/14P6ln2, and has a blog containing articles on IT security fundamentals and commentaries relating to current developments at http://www.ceilers-news.de

Carsten has also written a book on the subject of 'HTML5 Security' for Developer.Press available to buy for only $3.99. You can purchase his book here: HTML5 Security

Comments

  1. scottmattocks says:

    WebSocket connections start as a simple HTTP upgrade request. Is it not up to the server that handles that request to respect the Same Origin information at the time of the connection? I don’t know that there is an inherent security flaw in the negotiation of the WebSocket handshake. It appears to me that a proper server implementation can limit security risks. What am I missing?

    Also, you talk about vulnerabilities that exist because the request could come from a non-browser client. Does this same threat not exist for standard HTTP requests? How are WebSockets less secure than HTTP because of this?

  2. worldsight says:

    This argument doesn’t make any sense. WebSocket doesn’t behave any differently than http: you can open a specific web page in your browser, and that web page can make an http connection to another site via javaScript. Cross site policy requires only that the browser tell any site if there is a violation of origin. For example, Facebook sign in on this very blog makes a JS connection to Facebook to get credentials. Facebook allows the incoming connection if the website trying to make the connection is authorized to do so. It’s not up to the browser, it’s only up to the server to allow or deny. The only thing the browser has to do is to send the site identity making the request. WebSocket behaves in exactly the same way. The first handshake is http based anyway, and it’s up to the server to upgrade to WS or WSS if cross origin is allowed or not. it’s a mis-representation of the facts to say that a hostile web page can start sniffing all the ports. If you have an internal port with a webSocket server that is not secure, then that’s where the security hole is. There are great webSocket servers that are secure, and there are bad webSocket server implementations that are insecure. It has nothing to do with webSocket.