Your grandma has been coding web sites since 1994, and has lately been getting deep into HTML5. But as her web app security advisor, would you recommend she code with WebSockets? Let’s look at the research we did for our talk on Hacking with WebSockets presented at Black Hat USA 2012, and see if we can help grandma out.
As defined in the RFC 6455 spec, “the WebSocket Protocol enables two-way communication between a client running untrusted code in a controlled environment to a remote host that has opted-in to communications from that code.” By providing a nice mechanism for low-latency, two-way communication, it removes the need for workarounds that force persistent connections via the inherently non-persistent HTTP protocol via polling. You can think of WebSockets as a replacement for the “x” in Ajax, but with some additional features. At first glance, it’s just what grandma needs to build out her super fast interactive knitting application.
“Old” Security Still Matters
Web apps that use WebSockets are susceptible to all existing issues that "old" Web apps had. Things like XSS and MITM are still as important as ever. Any attacker that can sniff “http:” can also sniff “ws:”, meaning they can use the same methods to intercept the traffic or inject into the traffic. So WebSockets is just a new way to encounter the same security problems you see with HTTP.
Although it should be impossible to mix “ws:” with “https:” according to the RFC 6455, which is a nice improvement, not all of the browsers adhere to that rule. For now, only Firefox implements this policy. This is similar to having HTTP resources loaded within an HTTPS page. In some cases, the insecure portion of the web application may compromise the whole system.
Another old friend, denial of service (DoS), is also possible with WebSockets. WebSockets typically have a higher connection limit than HTTP, so it’s possible for a malicious web site to exhaust the browser by grabbing the maximum number of WebSockets connections, which could crash your browser. All major browsers are known to have that limit set to a number as high as 900 to 3000, and only Firefox limits connections to 200.
It is also possible for a client to DoS a server by requesting a large number of connections from the server. Attacks like SlowLoris strive to maintain persistent connections, thus draining server resources. This happens automatically with WebSockets, which keep the connection alive by design.
IPS / IDS / DLP and Masking
Malicious users can also bypass security devices by establishing covert channels inside legitimate WebSocket data frames. Reserved flags, length representations and even the mask values can be used to move data to and from the client even when standard protection mechanisms are in place.
For an example of how easy it is to communicate with a compromised browser via WebSockets, see The Tiny Mighty Waldo.
Inspection / Manipulation Tools
In order to understand Websockets security support by sniffing and traffic manipulation, you need tools. For now there is very limited support of WebSockets on this front. Wireshark, Fiddler and Chrome Developer Tools are some of the first to implement read-only support for WebSocket data frames. ZAP is working on comprehensive support, complete with data frame fuzzing. But until these support more sophisticated features, developers don’t have much help creating secure WebSocket applications.
Since WebSockets is missing security features like HTTP cookies and form-based authentication, secure deployment is going to be a mix of HTTP and WebSockets, or something entirely new.
We are continuing to research the details of the protocol and working out better approaches to implement a robust and secure system using WebSockets, and hope to publish more on this topic. In the meantime, these two simple suggestions will go a long way to keep your grandma safe:
- Adopt WebSockets if you need higher throughput, full duplex communication or lower latency.
- Remember security basics (authentication/authorization, session management, state handling), as WebSocket protocol isn't aware of these.