Usually, when you are trying to access a website, your browser sends an HTTP request to the webserver which is hosting the page. The server processes your request and sends the response. After receiving the response, the browser renders the web page. After this process is completed, the server connection will be closed until the server receives a new request.
Nowadays, the need for accessing information in real-time has increased. When you are trying to view live sports scores, you want the scores to be updated instantaneously, rather than reloading the webpage every time you want to view the scores. Numerous attempts were made to provide this information in real-time; methods such as long-polling were used. But, this method wasn't entirely useful, as it increased the latency. This issue was solved by the use of WebSockets.
What are WebSockets?
WebSockets allow you to open two-way communication between your browser and a server without having to constantly check the server for a reply. The connection made between your browser and the server is persistent. With the help of WebSockets, two or more computers can communicate with each other, at the same time, over a single network connection.
The sockets in WebSockets come into play when the server receives some new data. This data is then transferred to the client through the socket.
The WebSocket protocol was implemented as an upgrade for HTTP. Its main goal was to remove the need for opening multiple HTTP connections while trying to establish two-way communication with servers.
Application of WebSockets
The use of a WebSocket can be easily understood by examining the example of a chat room:
Let's assume that there's a chat server. Client 1 opens their browser and joins the chat room, which creates a socket connection to the chat server. Now, Client 2 and Client 3 join the server. After seeing this, Client 1 types "Hello" in the chat room. This message will now be sent to the server through the socket, which would automatically send the message to other clients in the chat room.
- The server listens for any messages sent by the client.
- As soon as the server receives a message from the client, it sends the message through the socket connection to the other clients connected to the chat room.
- This process is repeated until the client leaves the chat room.
Creating a WebSocket Program
Now since we have a basic understanding of what WebSockets are, let's create our WebSocket program, to understand more about how they work.
- Basic knowledge of Python is required for understanding this topic.
Let's start with creating two files, server.py and client.py
First, let's set up a server by modifying server.py:
Import the socket module
- This python module is used for socket programming.
For the clients to connect, it is necessary to enable the server to accept connections.
- s.listen(1) » Enables the server to accept a specified number of connections.
- s.accept() » Accepts a connection.
After successfully connecting to the server, we have to make the client listen for connections; we have to make the client listen for connections.
That's it! Now the WebSocket server and client are configured to receive and send messages.
Cross-Site WebSocket Hijacking (CSWSH)
Cross-Site WebSocket Hijacking is basically a Cross-Site Request Forgery (CSRF) attack performed on a WebSocket protocol.
How to exploit this vulnerability?
- This vulnerability can be exploited first by creating a webpage.
- Next, the webpage should initiate a WebSocket handshake with the victim's server.
- Once a connection has been established, your webpage can send requests to the server, via the established connection, and obtain the responses that are sent back from the server.
Cross-Site WebSocket Hijacking can lead to:
- WebSocket-based CSRF » Attackers can perform state-changing actions on behalf of the user.
- Obtaining private data » Cross-Site WebSocket hijacking allows the attacker to establish a two-way connection with which the attacker can just listen for any incoming server messages and retrieve any leaked information from these server messages.
How to prevent this vulnerability?
- Origin Header Check » Origin headers are usually set to the URL, which originates the WebSocket request.
- CSRF Tokens or Any Unpredictable Value » An unpredictable token which is placed in a WebSocket handshake request and validated server-side before the connection is established can prevent this vulnerability.
Real-World Attack Scenario: In the HackerOne report shown below, the security researcher showed how they found and exploited a Cross-Site WebSocket Hijacking vulnerability on a target website.
The security researcher discovered that a WebSocket channel was not checking the Origin Header, which led to the Cross-Site WebSocket Hijacking attack. The impact of this attack was that an attacker could have forced a victim to do any operations available within the WebSockets communication, and the attacker could have also read any sensitive information.
Vulnerabilities that exist in web applications exist in WebSockets too. Vulnerabilities such as File Inclusion, Error-based SQL Injection, Blind SQL Injection, Reflected XSS, Stored XSS, Command Execution, XXE, Client/Server Denial of Service, and more!
- For deploying WebSockets securely, the HTTP handshake should be implemented properly.
- Usage of wss:// protocol for secure transport.
- Treating client and server data as untrusted.