Cross-site WebSocket hijacking (CSWSH)

 

What is WebSocket?

WebSocket is, like HTTP, a communications protocol that enables interaction between a browser and a web server.
The WebSocket protocol allows both servers and browsers to send messages to each other using a single TCP connection.

This is very useful when trying to create real-time applications such as online games and live chat. For example, Slack’s web app uses WebSocket connections to sync messages in its chat functionality.


In order for a web application to sync in real-time, web servers need to be able to actively push data to its clients. And this is where WebSocket comes in.


Traditionally, HTTP only supports client-initiated communications. This means that every time the real-time application needs to be synced (for example, an online game updating its live leaderboard), the client’s browser would need to send an HTTP request to retrieve the data from the server.

When an application is constantly doing this type of update, this traditional method incurs a lot of unnecessary overhead and ultimately slows down the application.

Whereas the WebSocket protocol solves this problem by creating a persistent connection between the client and the server that allows both client and server-initiated data transfers.

During the lifetime of a WebSocket connection, the client and the server are free to exchange any amount of data without incurring the overhead and latency of using traditional HTTP requests.

How are WebSocket connections established?

A WebSocket connection between a client and a server is established through a WebSocket handshake.


This process is initiated by the client sending a normal HTTP or HTTPS request to the server with the special header: “Upgrade: websocket”. If the server supports WebSocket connections, it will respond with a 101 status code (Switching Protocols). From that point on, the handshake is complete and both parties are free to send data to the other.


Side note: WebSocket uses the ws:// URL scheme, and the wss:// URL scheme for secure connections.

WebSocket connections are normally created using client-side JavaScript like the following:

The wss protocol establishes a WebSocket over an encrypted TLS connection, while the ws protocol uses an unencrypted connection.

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.

Note

Several features of the WebSocket handshake messages are worth noting:

  • 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.
  • The Sec-WebSocket-Key request header contains a Base64-encoded random value, which should be randomly generated in each handshake request.
  • 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 Sec-WebSocket-Key header contains a random value to prevent errors from caching proxies, and is not used for authentication or session handling purposes (It’s not a CSRF token).

Websockets Enumeration

You can use the tool https://github.com/PalindromeLabs/STEWS to discover, fingerprint and search for known vulnerabilities in websockets automatically.

Cross-site WebSocket hijacking (CSWSH)

Also known as cross-origin WebSocket hijacking.
It is a Cross-Site Request Forgery (CSRF) on a WebSocket handshake.


It arises when the WebSocket handshake request relies solely on HTTP cookies for session handling and does not contain any CSRF tokens or other unpredictable values.
An attacker can create a malicious web page on their own domain which establishes a cross-site WebSocket connection to the vulnerable application. The application will handle the connection in the context of the victim user’s session with the application.

Structure of an attack

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.

Simple Attack

Note that when establishing a websocket connection the cookie is sent to the server. The server might be using it to relate each specific user with his websocket session based on the sent cookie.


Then, if for example the websocket server sends back the history of the conversation of a user if a msg with “READY” is sent, then a simple XSS establishing the connection (the cookie will be sent automatically to authorise the victim user) sending “READY” will be able to retrieve the history of the conversation.:

Stealing data from user

Copy the web application you want to impersonate (the .html files for example) and inside the script where the websocket communication is occurring add this code:

Now download the wsHook.js file from https://github.com/skepticfx/wshook and save it inside the folder with the web files.


Exposing the web application and making a user connect to it you will be able to steal the sent and received messages via websocket:

The impact of Cross-Site WebSocket Hijacking

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.

How to prevent Cross-Site WebSocket Hijacking

In order to prevent Cross-Site WebSocket Hijacking, an application would need to deny WebSocket handshake requests from unknown origins. There are two ways this can be achieved:

  • Check the Origin header: browsers would automatically include an Origin header. This can be used to validate where the handshake request is coming from. When validating the Origin of the request, be sure to use a whitelist of URLs instead of a blacklist, and use a strict and rigorously tested regex expression.
  • Use CSRF tokens for the WebSocket handshake request: applications could also use a randomized token on a WebSocket handshake request and validate it server-side before establishing a WebSocket connection. This way, if an attacker cannot leak or predict the random token, she will not be able to establish the connection.

WebSocket is a big part of many modern applications. However, it is often overlooked as a potential attack vector.

As Web Sockets are a mechanism to send data to server side and client side, depending on how the server and client handles the information, Web Sockets can be used to exploit several other vulnerabilities like XSS, SQLi or any other common web vuln using input of s user from a websocket.

Post a Comment

Previous Post Next Post