
BLOG
BLOG
WebSockets is a bi-directional, full-duplex communications protocol initiated over HTTP. They are commonly used in modern web applications for streaming data, Chat applications, and other asynchronous traffic. It is a protocol where the client and server can send the messages simultaneously over the channel.
When it comes to WebSockets, we generally encounter the following security testing methodologies:
We know how in black box testing, an entity is tested without much knowledge about its internal structure or design. Let’s find out how black box testing is conducted in the case of WebSockets.
This can be done by inspecting the client-side source code of the application for the presence of ws:// or wss:// URI (Uniform Resource Identifier) scheme. Developer tools of browsers like Google Chrome can also be used to view the Network and WebSocket communication. ZAP’s WebSocket tab could also be used for the same purpose.
Resources like websocket.org also offer ways to drive WebSocket tests. They let the users save a piece of code locally into their PCs and run that code in the browser to open a WebSocket connection and run the required test. One could also use the developer tools in the browser to process WebSocket requests directed to locally hosted APIs.
In the WebSocket standard, an origin header field is defined which is generally used to differentiate between the connections coming from different hosts and also the connections established between the browser and another network client. Origin headers are basically added by the user agents to elaborate the security contexts which led the user agent to start an HTTP request. These origin headers are later used by the HTTP servers to prevent and mitigate the Cross-Site Request Forgery (CSRF) vulnerabilities.
If the Origin header is not verified during the initial WebSocket handshake, the server may accept connections from any origin and this may result in serious security vulnerabilities. The origin header can be verified by using a WebSocket client to attempt to connect to the remote WebSocket server. In case a connection is established, this would mean that the origin header is not being verified in the WebSocket handshake.
In order to maintain the confidentiality and integrity of information during the entire process, it is essential to verify that the WebSocket connection uses SSL to transport sensitive wss:// information. It is also essential to check the SSL implementation for security issues.
WebSockets are not known to handle authorization/authentication and that is why normal black-box tests should be carried out for them. This means that if a WebSocket is opened via a page, it doesn’t receive any kind of authorization/authentication and you need to take some extra steps in order to secure the WebSocket connection. You can also use the same authentication measures you are using on your web views for your WebSocket connections too.
Injection attacks are as probable over WebSockets as they are over any other mechanism like the HTTP connections. Three of the top five website vulnerabilities namely Cross-site Scripting, SQL Injection and Remote File Inclusion can be attributed to input sanitization. Some of the common pathways which hackers use to alter user input data and infiltrate into WebSockets include GET requests, POST requests and cookies. That is why if the data is coming from an external client, input sanitization must be done before processing it.
Input sanitization essentially means the cleansing of the user input in order to prevent it from exploiting the security loopholes in the system. But, it’s important to understand that thorough sanitization of user input is not an easy task. And the best approach one can follow while handling this tough task is to focus on the context in which the user input will be utilized.
Simple measures like sanitizing data before output, enclosing attributes within quotes, and escaping user inputs before including them in SQL queries can go a long way and prevent attacks and exploits which might result because of poor input sanitization.
In the case of grey-box testing, the tester has only partial knowledge about the application structure. The only major difference from black-box testing is that the pen-tester may have the API documentation in this case which might include information related to WebSocket requests and responses.
HTTP is a half-duplex stateless protocol where the client sends a request to the server and then waits for the server’s response whereas, in the WebSockets, it is a full-duplex stateless protocol that is initiated over HTTP and is long-lived. It doesn’t wait for the server to respond back, instead, the client can send any number of requests to the server.
A full-duplex and persistent connection means that instead of the conventional request and response, the WebSocket connection stays active for as long as the application is in running state and allows simultaneous communication between the client and server because it is full-duplex.
WebSockets are preferred in the applications which require low latency communication. Although both HTTP and WebSockets have equal sized initial handshakes for connection, in case of WebSockets, the handshake is performed only once.
Efforts are being made to improve the latency and performance of HTTP protocols, but it is still likely that WebSockets will always have an edge in terms of latency when it comes to client to server data transfer.
WebSocket connections are normally created using client-side JavaScript like the following:
var ws = new WebSocket("wss://normal-website.com/chat");
To establish the connection, the browser and server perform a WebSocket handshake over HTTP. The browser issues a WebSocket handshake request like the following:
If the server accepts the connection, it returns a WebSocket handshake response like the following:
At this point, the network connection remains open and can be used to send WebSocket messages in either direction.
● The Connection and Upgrade headers in the request and response indicate that this is a WebSocket handshake.
● The Sec-WebSocket-Version request header specifies the WebSocket protocol version that the client wishes to use. This is typically 13 and is not a vulnerable parameter.
● The Sec-WebSocket-Key request header contains a Base64-encoded random value, which should be randomly generated in each handshake request. This header is not the one which uniquely identifies a user or can be used for authorization purposes.
● The Sec-WebSocket-Accept response header contains a hash of the value submitted in the Sec-WebSocket-Key request header, concatenated with a specific string defined in the protocol specification. This is done to prevent misleading responses resulting from misconfigured servers or caching proxies.
● The wss protocol establishes a WebSocket over an encrypted TLS connection, while the ws protocol uses an unencrypted connection. So if the server is accepting connections from ws protocol it is vulnerable to MITM attacks.
● This protocol doesn’t prescribe any particular way that the servers can authenticate clients during the WebSocket handshake. The WebSocket server can use any client mechanism available to a generic HTTP server, such as cookies, HTTP authentication, or TLS authentication.
WebSockets does not follow same-origin-policies.
The number of tools which can test WebSocket implementations is not that large. However, the two best-known tools for the security testing of WebSockets are ZAP and Burp. With the help of these tools, you can intercept and improvise WebSocket frames with ease.
You can also use the Chrome development tools to keep a check on the WebSocket traffic. Once you identify the most suited tool for your purpose, the rest of the security audit part for WebSockets (access rights tests, injection tests, workflow tests) is nearly similar to that of general HTTP requests. If the protocol of the WebSocket is vulnerable to expansive attack surfaces, focusing on the configuration part can limit the risks manifold, as is the case for HTTP protocols.
In order for the identified security testing tool to work properly, it must have some crucial features present. Here is a list of some of those security testing functions:
The tool must be able to open a WebSocket connection to the server. The server can either be used with non-encrypted (ws://) or encrypted (wss://) connection. The features of manipulating the Origin Header and support of user-provided subprotocols should also be there.
If the user or the WebSocket server requests, the tool must be able to close the WebSocket connection as well.
The tool should be able to send/receive user-provided and server-provided messages and also keep the connection alive. Message formats like UTF-8 and binary must be supported by the tool as well.
The tool must be able to log data being sent to the log functions and also log all the WebSocket messages while the connection is in a live state. All the logs must be maintained on files as well.
The tool should support user input and be able to handle and process it as well.
The WebSocket security tool should also be able to print essential data to any user interface for informational or documentation purposes.
The security tool should also support the use of HTTP proxies.
A Cross-Site WebSocket Hijacking attack is essentially a CSRF on a WebSocket handshake.
When a user is logged into victim.com in her browser and opens attacker.com in the same browser, attacker.com can try to establish a WebSocket connection to the server of victim.com.
Since the user’s browser would automatically send over her credentials with any HTTP/ HTTPS request to victim.com, the WebSocket handshake request initiated by attacker.com would contain the user’s legitimate credentials.
Related Topic- Understanding OWASP Top 10: Cross Site Scripting (XSS)
This means the resulting WebSocket connection (created by attacker.com) would have the same level of access as if it originated from vicitm.com .
After the WebSocket connection is established, attacker.com can communicate directly to victim.com as a legitimate user.
To carry out the attack, an attacker would create a script that will initiate the WebSocket connection to the victim server. She can then embed that script on a malicious page and trick a user into accessing the page.
When the victim accesses the malicious page, her browser will automatically include her cookies into the WebSocket handshake request (since it’s a regular HTTP request).
The malicious script crafted by the attacker will now have access to a WebSocket connection created using the victim’s credentials.
Using a hijacked WebSocket connection, the attacker can now achieve a lot of things:
WebSocket CSRF: If the WebSocket communication is used to carry out sensitive, state-changing actions, attackers can use this connection to forge actions on behalf of the user. For example, attackers can post fake messages onto a user’s chat groups.
Private data retrieval: If the WebSocket communication can be used to retrieve sensitive information via a client request, attackers can initiate fake requests to retrieve sensitive data belonging to the user.
Private data leaks via server messages: Attackers can also simply listen in on server messages and passively collect information leaked from these messages. For example, an attacker can use the connection to eavesdrop on a user’s incoming notifications.
The key takeaways when it comes to WebSocket security are as follows:
When it comes to security, WebSockets are often ignored by security practitioners. It must be made a regular practice to examine WebSocket traffic and other security parameters using tools like ZAP and Burp Suite and even use developer tools from the browsers to do that. Preferably this should be done during the penetration testing phase.
Although a cookie may be returned on the same request that initiates a WebSocket, it doesn't mean that cookie has anything to do with the WebSocket protocol. Your browser's protocol changes to establish a WebSocket connection.
In this process, however, the server doesn't get any cookies to validate the established connection. Generally, if an application is using WebSockets, you must examine its traffic and determine if any substitute method of authentication or authorization is taking place. Chances are that you won't find any such instance.
WebSockets are not affected by the Same Origin Policy and the corollary CORS, i.e. Cross-Origin Resource Sharing. But why so? This is because WebSockets are an entirely different protocol from the HTTP.
Most of the security solutions make this assumption that the WebSockets will follow the same rules as the HTTP traffic, but this is not the situation. And this becomes very important to understand while testing them.
Most of the typical security scanners won't detect the serious authorization and authentication flaws that might exist in WebSockets. In order to detect such vulnerabilities, it is important to know where to look for what and thoroughly understand the context. That is why penetration testing techniques should be the go-to method in case of WebSockets.
Also, the previously explained methods of black and grey box testing of WebSockets will also ensure a thorough security analysis of all the involved mechanisms.
● OWASP Zed Attack Proxy
● Burp Suite
● Google Chrome Simple Web Socket Web client
● Cross-Site WebSocket Hijacking Tool
Related Topic- 12 Best Penetration Testing Tools for Security Assessment
The WebSocket landscape is continuously evolving and along with it are evolving the associated security vulnerabilities. One thing which needs to be understood is that every WebSocket isn’t a vulnerability. However, if a WebSocket vulnerability is encountered, it must be treated with high priority. Moreover, the organizations dealing with WebSockets must be extra cautious and understand the importance of implementing all the security controls in place when it comes to WebSockets.
Stay ahead of emerging threats, vulnerabilities, and best practices in mobile app security—delivered straight to your inbox.
Exclusive insights. Zero fluff. Absolute security.
Join the Appknox Security Insider Newsletter!