code

WebSocket Misconfigurations

Written by Yuval Donana on

WebSocket Misconfigurations

Written by Yuval Donana on


Introduction

WebSocket allows real-time communication between clients and servers. The WebSocket protocol was created in 2010 (RFC6455) to provide a low-overhead web protocol. It is gaining popularity as an essential component of web application development, where real-time communication is a key factor. However, despite its many benefits, the WebSocket protocol can pose significant security risks.

The WebSocket Protocol

The WebSocket protocol can be found in the application layer of the OSI model and allows a client and server to perform a full duplex communication over a single, long-lived connection, which will remain open until closed. Unlike HTTP, WebSocket does not use a request-response approach and has a lower overhead. Once the connection is established, the server and the client can send data, making the protocol ideal for real-time applications such as online games, chat applications, and live data streams. To understand the protocol better, take an online chat application as an example, without WebSocket, the application will have to make a request to the server every few seconds to receive new messages. With the WebSocket protocol, the server does not have to wait for a request from the client and can push the new message immediately. This means that WebSocket allows for faster and more efficient communication, making it well-suited for real-time applications where rapid data exchange is critical.

The Way a Connection is Made

To establish a WebSocket connection, the client sends an HTTP request to the server, including an Upgrade: WebSocket header indicating the will to upgrade to a WebSocket connection. The server responds with an HTTP response that includes a Connection: Upgrade header indicating that the upgrade has been accepted. Once the connection is established, data can be sent and received in real-time using the WebSocket protocol.

Common Attack Vectors

To gain a better understanding of how NoSQL queries work and where they can be vulnerable to injection attacks, let’s examine  MongoDB, the most popular NoSQL database. In the following example, we will utilize PHP to access MongoDB and demonstrate a simple example to implement authentication:

Misconfigurations in the WebSocket protocol could allow an adversary to perform a wide range of attacks against the application. Following is a comprehensive explanation of several commonly used attack vectors:

Advanced NoSQL Injection

Cross-Site WebSocket Hijacking (CSWH) is an attack that exploits the vulnerability of WebSocket to steal sensitive information. Since the initial connection is based on HTTP, cookies scoped to the server’s domain will also be sent when the client sends the initial request for an upgrade. Adversaries can exploit this behavior to perform unauthorized actions or fetch sensitive information.
For example, consider a live chat web application that responds with the user’s messaging history upon receiving a “GetHistory” message from the client. An adversary can host a web page that contains the following JavaScript code:

The above snippet will create a new WebSocket connection to example.com. Once the connection is made, a “GetHistory” message will be sent to the server.

Once a user of example.com loads the webpage, the JavaScript code will be executed, and if the user’s cookies are valid, a connection will be established without the victim’s knowledge, making it possible for the adversary to access the victim’s sensitive data.

Mitigation

To mitigate this vulnerability, the WebSocket server should verify the authenticity of the connection, validating the origin of the HTTP request for an upgrade using the Origin header. A more resilient approach would be to apply a CSRF token. The token must be created on the server, randomly chosen, and impenetrable. The request must verify the token before performing any operation.

Denial Of Service (DOS)

When a client establishes a WebSocket connection with a server, it initiates a new TCP connection to the server. This protocol is built on top of the TCP protocol, and each WebSocket connection operates independently of other connections. Therefore, if a client needs to establish multiple WebSocket connections to a server, each connection will require a separate TCP connection. This can have a high impact on the server’s performance.
For example, consider an e-commerce website that uses WebSocket to provide real-time updates on product availability to its customers. An attacker who wants to disrupt the website’s operations launches a WebSocket DoS attack. The attacker creates a script that generates a large number of WebSocket connections to the e-commerce website’s server, overwhelming it with a large number of connections:

WebSocket

The above script initiates a new connection based on the provided argument. For example, 10,000 connections can be created simultaneously to the server. As the server attempts to handle all the incoming requests, it becomes overloaded and slows down. While the number of connections increases, the server eventually becomes unresponsive, and users can no longer access the system.

Mitigation

Multiple measures can be taken to mitigate the WebSocket Denial of Service (DoS) risk. For instance, the amount of data a user can send within a specified time frame can be limited. At the same time, the overall data processing capability of the server can be monitored and capped. In addition, both the number of concurrent WebSocket connections per user and overall can be restricted. These measures prevent the server from becoming overwhelmed by excessive data and connections, reducing the likelihood of a DoS attack.

WebSocket Smuggling

Websocket smuggling is a type of attack that exploits the this protocol to bypass network security measures and gain unauthorized access to a server or a network. Even though the vulnerability does not originate from the said protocol, it is an integral part of the exploitation part.
To better understand the vulnerability, we need to understand how reverse proxies handle a WebSocket connection. As mentioned earlier, the connection is established by sending an HTTP upgrade request, and once the server responds with a “Switching Protocol” response, the connection is established. Some reverse proxies do not check for the response status code. As a result, it is possible to trick the reverse proxy into thinking the connection was established, thus creating a TCP connection between the client and the backend server, as shown in the following image:

WebSocket
Direct TCP\TLS Connection Scheme to the Backend Server

This attack vector can be divided into the following steps:

  • The client sends an Upgrade request to the reverse proxy server with an intentionally wrong protocol version inside the Sec-WebSocket-Version header.
  • The proxy server fails to validate the header and assumes the Upgrade request is correct. It then forwards the request to the backend.
  • The backend responds with an HTTP 426 Upgrade Required status code because the protocol version is incorrect inside the Sec-WebSocket-Version header. However, the reverse proxy server does not check the response completely from the backend, including the status code, and assumes that the backend is ready for WebSocket communication.
  • The proxy then forwards the request back to the client. At this point, the reverse proxy server believes that a WebSocket connection has been established between the client and the backend, even though the backend has refused the Upgrade request.
  • The proxy server keeps the TCP or TLS connection (between the client and the server) open. The adversary is able to access the private REST API by sending an HTTP request over the open connection.
  • The proxy server will forward the request to the backend, which will respond as if the request came from a legitimate client.

Mitigation

To prevent this type of attack, it is essential to implement strict WebSocket protocol parsers on the server side and to configure the reverse proxy server to reject it’s messages that do not comply with the WebSocket protocol specification. Moreover, the reverse proxy server should be configured to validate all responses from the backend, including the status code, to prevent misinterpretation of the backend’s intent.

References