WebSockets is a modern HTML5 standard which makes communication between client and server a lot more simpler than ever. We are all familiar with the technology of sockets. Sockets have been fundamental to network communication for a long time but usually the communication over the browser has been restricted. The general restrictions
- The server used to have a permanent listener while the client (aka browser) was not designated any fixed listener for a more long term connection. Hence, every communication was restricted to the client demanding and the server responding.
- This meant that unless the client requested for a particular resource, the server was unable to push such a resource to the client.
- This was detrimental since the client is then forced to check with the server at regular intervals. This meant a lot of libraries focused on optimizing asynchronous calls and identifying the response of asynchronous calls. Notably the most common approach was to create on the fly functions with different names as callback functions. This can be witnessed here. In you open your console log and observe the network, you would notice how many connections are being made for this task. Pinging the server is not the problem but the amount of work involved in setting up a new connection everytime is. This is however essential in the old HTML standard to ensure that the client is never directly attacked by anyone.
Modern technologies have made it possible to sandbox the browser on a whole new scale thereby making it possible for riskier modes of access to be made. Hence a lot of newer technologies have been introduced including WebSockets. WebSockets is slightly different then the standard socket implementation. In this case the protocol is still http[s] and this makes it more versatile (it has no problems in working with http proxies). The protocol is itself symbolized by ws[s]:// and it keeps the established connection open to continuous send or receive messages. WebSockets is an important and interesting protocol whose importance cannot be understated. I think that a growing number of web developers will try to implement WebSockets into their websites and it is going to be an undeniably dominant technology in the years to come.
I think that a growing number of web developers will try to implement WebSockets into their websites and it is going to be an undeniably dominant technology in the years to come.
So before we jump into the security problems of WebSockets let me show some use cases of WebSockets.
-
Comments / Message notification in the website. This is a common use case in several application where the user needs to be notified on new comments or messages. There are ui components such as the notifications api (albeit still in draft) or the user defined components. These can be updated from any JS ofcourse. The usual update sequence has been from AJAX calls. However with WebSockets, we can make that relatively simpler since the server would send any updates when needed and the number of pings needed are very low thereby reducing both the client and server footprint.
-
Common editing platforms With the advent of HTML5, shared editing is becoming very popular. Tools from google docs, word on the web, open source projects like etherpad etc have made it a reality. Though I cannot attest to the technology behind these tools in particular, I can definitely say that WebSockets can make this possible in a native manner. Since WebSockets follows the rules of http, the authorization mechanisms and sessions you have in place as part of your existing application also carries forward.
-
Monitoring solutions In many cases we all monitor our servers, loads etc. and we use a http front end to see such activities in so-called real-time. The truth is this is not as real-time as we presume since the cost to establish a secure tunnel is significant. WebSockets significantly reduce such latency for any real-time monitoring.
I know all the things I have said above make it difficult to justify that the current WebSocket specification itself poses some serious risks.
There have been some well known problems on the server side of the WebSockets and the most common solution has been to check the origin tag. The discussions on this topic have even expanded to include the forgery of such socket communication despite the existence of the origin tag by re-routing the socket channel from the server instead of relying on the browser. While these are very valid problems my views on the subject is that we are not looking at the elephant in the room.
In the pursuit of securing the server, we often forget the end-user of the web-browser. Let us look at why WebSockets are so special that they represents a breaking point in HTML5.
Over so many years, we have been pushing for extended features in HTML5 that we have seemingly forgotten some of the design choices we made earlier. HTML5 does give us unlimited opportunities that the mere size of one article would never be able to cover. So I will restrain myself and talk only about a few things I would like to mention.
The first and foremost of them all is the beauty of CORS. CORS is a beauty in itself since it allows us to use a proper XMLHttpRequest across origins and achieve our purpose. Ok, let me go back to layman terms. In the browser, one of the major blocks of security has been the Same-Origin Policy. For those who understand SOP, please skip ahead to the next paragraph. The same-origin policy prevents a request made from one page to another if their origin is different. i.e. lets say http://yourwebsite.com
wants to ask something from http://mywebsite.com
, the browser would block it. This block meant that developers went around and over to find all the loopholes to overcome this. The browser allowed some resources to be shared (including scripts, images, video objects and such) and the developers used this mercilessly. The most used of this mechanisms is the use of JSONP.
I will write a separate article on JSONP but know that it uses the script tag's source attribute to make GET requests to cross-domain servers. Over the years, developers have been educated on the ill effects of JSONP and encouraged to add specific headers so as to be careful. Today one can bypass the use of JSONP completely by using CORS. The beauty of CORS allows one to send all kinds of request (note: JSONP allows only GET) to other domains.
Now we are almost getting off topic. So let me get back to WebSockets. I needed to provide CORS as an example because it matters significantly here. We have made a XMLHttpRequest so neat and well-balanced with proper support of a whitelist. In security, we always argue that a whitelist is better than a blacklist for obvious reasons. WebSockets is a nightmare because it does not come under the Same-origin policy.
WebSockets is a nightmare because it does not come under the Same-origin policy.
Thanks For the Excellent Information !