яIntroduction: WebSocket in a modern web
WebSocket is a communication protocol that provides a two-way data transmission channel over a single TCP connection.
WS Protocol: handshake, frames, opcodes
The Client sends an HTTP request (GET method) and, if successful, the server returns an HTTP response with a status code 101 (Switching Protocols) that it indicates that the server has accepted a request from HTTP to a permanent WS protocol. HTTP and WebSocket clients can connect to the server via the same port, as the connection order (handhhake) uses the HTTP protocol.
After the handshake procedure is completed, the client and the server can exchange messages with data (text or binary) and control messages (Close, Ping, Pong) at any time. The message consists of one frame, if it is not fragmented, or at least two frames, if it is fragmented.
Fragmentation breaks the message into two or more frames. It allows you to send messages when the initial data is already available, but their total length is still unknown. Without fragmentation, the entire message should be transmitted in one frame, so to send even the first byte you need to know the full length of the data, which requires the use of a buffer.
So that the recipient understands what type of data has come to him and what to do with them, at the beginning of each frame, an Opcode is sent.
Opcode occupies 4 bits in the frame header. This means that theoretically possible codes can be 16 and RFC 6455 divides them into 3 categories: test/binary data, service commands, and reserved codes.
WebSocket vs HTTP: security model
Each HTTP request is insulated (if you do not consider sessions at the application level). Authentication occurs through headlines, cookies, or TLS certificates.
WebSocket does not have its own built-in authentication mechanism, "authentication" occurs precisely within the framework of WebSocket handshake, which is an HTTP request (with the headings Upgrade: websocket, Sec-WebSocket-Key, etc.). After Handshake is completed, the headlines are no longer transmitted. If a hacker can intercept or replace the TCP connection, he will have full access without the need to re-authelicit.
There is no difference between the protocols, both use TLS. Use unprotected ws:// – huge risk. Not only is the traffic open, but intermediate proxy servers often do not understand the pure WebSocket on the 80 port and simply cut off the connection. wss:// solves the problem by packing frames in TLS.
In the case of HTTP, browsers strictly adopt SOP and CORS rules. A script from a left-wing site can’t just read the data from the bank’s API unless the bank explicitly allowed it through CORS headers.
In the case of WebSocket, it does not obey SOP at all. The browser will allow a script from any site to open a WebSocket connection to any server. Instead of locking, the browser does the following: When Handshake, it honestly adds the Origin header, and if the server sees an untrusted source, it resets the connection. If the developer forgets to check Origin, there is an attack by CSWSH – an analogue of the SSRF, but for web sects.
WebSocket has a feature. All frames sent from client to server must necessarily be disguised (i.e. a broken XOR frame data operation with a 32-bit random key that is generated by the client for each frame). Frames from server to client are not masked. It is protection against “stupid” or poorly configured proxy servers. If the client sends a predictable HTTP-like query via WebSocket without a mask, then the proxy server can confuse it with a regular HTTP request, caches a response from the server, and then give that cache to other users, which will lead to cache poisoning.
Intelligence
Unlike HTTP, where all endopitheses are visible in the documentation or easily move, WebSocket connections often “hid” behind default ports and specific ways.
Detection WebSocket endpoints
The most reliable way is to study the frontend of the application, since it is the client’s browser should know where and how to connect.
You need to look for traces of initialization in JS:
1. Ordinary constructors: new WebSocket (, WebSocket(
2. Look for the diagrams of protocols in the lines: ws://and wss://
3. We are looking for keywords of popular libraries: io(, SockJS, HubConnectionBuilder, $ActionCable
If the sources are empty, you have to move to the methods of overcoupation. Ffuff, dirb, gobster is not effective as they are looking for HTTP responses, and WS returns specific codes.
In order for the utility to understand that we are looking for WS, in each request when circulating the paths, be sure to specify the headlines of the protocol update.
Sometimes socket architecture is disclosed through related files or configuration errors.
To automate the detection process, you can use specialized software:
Websoc or wscat: CLI toots for quick checking. We can write a bash script that sorts the URL and tries to establish a connection:
Bash:
websocat –t {URL}
Or with the help of an extension for Burp Suite – WebSocket Smugler.
Analysis of messages and protocols
At this stage, the task is to understand how the application communicates through this open channel, what structure the data and what logical vulnerabilities can hide in them. Socket is only a transport, inside it can be “detailed” absolutely any protocol.
The first thing to see is the type of files sent in the Network tab (DevTools).
If the app uses Binary frames, you will have to figure out how to decode them. Popular binary format – Protobuf (Google Protocol Buffers).
MessagePack / BSON is JSON binary analogues.
Problems of authentication
The WebSocket protocol does not have built-in authentication mechanisms. This is the task of the developer.
Authentication by handshake
The most trivial error is when WebSocket does not check who connects at all.
No cookie, no tokens, just the title Upgrade: websocket. The attacker can connect to the socket directly and start listening to other people's messages, or send commands to the system from the anon, if the backend has not limited the rights.
Disadvantages of token checks
The server believes the token without checking it. What if the developer uses JWT? It can be decoded and changed to your own. Also, the server may not look at all at all on the token date and accept “extraterm”. Or you can change the algorithm from RS256 to HS256, sign the token with a famous key, and the backend will be entangled.
Preservation of the session via WS
This is an attack where the attacker will force the victim to use the known socket connection or a specific session identifier, then to intercept access to the account after the victim is authorized.
Authentication for each message
A more advanced WebSocket security design pattern, in which the verification of the rights and authenticity of the user is not once, but for each business logic frame being sent.
Bypassing authentication
The moment when the attacker has access to the data or commits actions to which his account does not have rights. The developers think that if the HTTP Handshake stage has been successful, then the entire subsequent default inside this TCP channel is safe and trusted, but this is not the case.
Control of the access channel
A mechanism that determines whether a specific connection has the right to subscribe to a specific channel/topic and send messages there.
The error of the developers is to open access to the channel only on the basis of the name that the client asks. The server believes that if the name of the channel contains UUID, then it is impossible to guess it, therefore, the verification of rights is not mandatory.
Channels are created so that users can listen to updates, but only a server or administrator should send messages there. If the rights to the channel are configured on the principle of "all or nothing", the user who subscribed to the public channel may find that the backend accepts the publication frames from him on the same channel.
IDOR via WebSocket IDs
Such a problem arises when the backend performs or returns sensitive data, blindly trusting the identifiers of the resources that the client sends extra-tie-text or binary frames, instead of verifying the rights of the session.
If the application uses ordinary serial numbers, then we simply change the number and get successful operation.
Injection attacks
Injections in WebSocket work as well as in a classic web application: the server blindly trusts the input data and executes them as a code.
XSS via WS messages
The JS malware code is transmitted inside WebSocket frames and is executed in the victim’s browser.
In standard web applications for distribution, Stored XSS needs the victim to go to a certain page, where the script will be loaded out of the database. In the WebSocket architecture, everything happens "on the fly" thanks to the Pub/Subclick model (Publish/Subscribe) or the bridgecat mechanism.
SQLi in WebSocket Parameters
Yes, it seemed that SQL injection only happens in HTTP requests, but no.
Although the mathematician and syntax of injections remain standard, the testing and operation process has unique nuances.
Most WAF only inspect the HTTP handshake phase. After the connection is established, all subsequent traffic is encapsulated in the WebSocket frames and often goes inside TLS encryption.
Command injection
The vulnerability of a critical level, as it gives RCE. A rare find for standard web applications, but it is regularly found in specialized ecosystems that use real-time protocols.
CSWSH
CSWSH or Cross-Site WebSocket Hijacking is an analogue of a CSRF attack for web sockets.
Mechanics Cross-Site WebSocket Hijacking
The attack is based on the properties of browsers and the features of the protocol specification. The victim is authorized to a legitimate and vulnerable site, enters the login / password. The server successfully authorizes it and installs a session cookie.
Without closing the tab, the user goes to the hacker’s website.
In the JS page stole a script that works automatically when downloaded. It is trying to install a WebSocket connection with a backend of the site.
The classic policy of a single source SOP would ban the script from a bad site to read answers from the legitimate one. But WebSocket SOP is not covered. The browser successfully forms a standard HTTP request Upgrade to a legitimate site and does 2 things:
1. Automatically attaches session cookies of a legitimate site, as the request goes to this domain.
2. Fills the Origin header, indicating where the request came from.
PoC and operation
To write PoC (Proof-of-Concept) we need 3 things:
• WebSocket URL: Exact endpoint address
• Type of authentication: If the application uses Cookies to authorize handshake
• Start message format: If the server requires a client to send some JSON immediately after connecting, copy it.
To demonstrate the operation:
1. Run a local server with a code that will perform the interaction
2. Simulate the victim: In the browser, open the tab and go to the local python norther
3. Analyze the conclusion
WebSocket is a communication protocol that provides a two-way data transmission channel over a single TCP connection.
WS Protocol: handshake, frames, opcodes
The Client sends an HTTP request (GET method) and, if successful, the server returns an HTTP response with a status code 101 (Switching Protocols) that it indicates that the server has accepted a request from HTTP to a permanent WS protocol. HTTP and WebSocket clients can connect to the server via the same port, as the connection order (handhhake) uses the HTTP protocol.
After the handshake procedure is completed, the client and the server can exchange messages with data (text or binary) and control messages (Close, Ping, Pong) at any time. The message consists of one frame, if it is not fragmented, or at least two frames, if it is fragmented.
Fragmentation breaks the message into two or more frames. It allows you to send messages when the initial data is already available, but their total length is still unknown. Without fragmentation, the entire message should be transmitted in one frame, so to send even the first byte you need to know the full length of the data, which requires the use of a buffer.
So that the recipient understands what type of data has come to him and what to do with them, at the beginning of each frame, an Opcode is sent.
Opcode occupies 4 bits in the frame header. This means that theoretically possible codes can be 16 and RFC 6455 divides them into 3 categories: test/binary data, service commands, and reserved codes.
WebSocket vs HTTP: security model
Each HTTP request is insulated (if you do not consider sessions at the application level). Authentication occurs through headlines, cookies, or TLS certificates.
WebSocket does not have its own built-in authentication mechanism, "authentication" occurs precisely within the framework of WebSocket handshake, which is an HTTP request (with the headings Upgrade: websocket, Sec-WebSocket-Key, etc.). After Handshake is completed, the headlines are no longer transmitted. If a hacker can intercept or replace the TCP connection, he will have full access without the need to re-authelicit.
There is no difference between the protocols, both use TLS. Use unprotected ws:// – huge risk. Not only is the traffic open, but intermediate proxy servers often do not understand the pure WebSocket on the 80 port and simply cut off the connection. wss:// solves the problem by packing frames in TLS.
In the case of HTTP, browsers strictly adopt SOP and CORS rules. A script from a left-wing site can’t just read the data from the bank’s API unless the bank explicitly allowed it through CORS headers.
In the case of WebSocket, it does not obey SOP at all. The browser will allow a script from any site to open a WebSocket connection to any server. Instead of locking, the browser does the following: When Handshake, it honestly adds the Origin header, and if the server sees an untrusted source, it resets the connection. If the developer forgets to check Origin, there is an attack by CSWSH – an analogue of the SSRF, but for web sects.
WebSocket has a feature. All frames sent from client to server must necessarily be disguised (i.e. a broken XOR frame data operation with a 32-bit random key that is generated by the client for each frame). Frames from server to client are not masked. It is protection against “stupid” or poorly configured proxy servers. If the client sends a predictable HTTP-like query via WebSocket without a mask, then the proxy server can confuse it with a regular HTTP request, caches a response from the server, and then give that cache to other users, which will lead to cache poisoning.
Intelligence
Unlike HTTP, where all endopitheses are visible in the documentation or easily move, WebSocket connections often “hid” behind default ports and specific ways.
Detection WebSocket endpoints
The most reliable way is to study the frontend of the application, since it is the client’s browser should know where and how to connect.
You need to look for traces of initialization in JS:
1. Ordinary constructors: new WebSocket (, WebSocket(
2. Look for the diagrams of protocols in the lines: ws://and wss://
3. We are looking for keywords of popular libraries: io(, SockJS, HubConnectionBuilder, $ActionCable
If the sources are empty, you have to move to the methods of overcoupation. Ffuff, dirb, gobster is not effective as they are looking for HTTP responses, and WS returns specific codes.
In order for the utility to understand that we are looking for WS, in each request when circulating the paths, be sure to specify the headlines of the protocol update.
Sometimes socket architecture is disclosed through related files or configuration errors.
To automate the detection process, you can use specialized software:
Websoc or wscat: CLI toots for quick checking. We can write a bash script that sorts the URL and tries to establish a connection:
Bash:
websocat –t {URL}
Or with the help of an extension for Burp Suite – WebSocket Smugler.
Analysis of messages and protocols
At this stage, the task is to understand how the application communicates through this open channel, what structure the data and what logical vulnerabilities can hide in them. Socket is only a transport, inside it can be “detailed” absolutely any protocol.
The first thing to see is the type of files sent in the Network tab (DevTools).
If the app uses Binary frames, you will have to figure out how to decode them. Popular binary format – Protobuf (Google Protocol Buffers).
MessagePack / BSON is JSON binary analogues.
Problems of authentication
The WebSocket protocol does not have built-in authentication mechanisms. This is the task of the developer.
Authentication by handshake
The most trivial error is when WebSocket does not check who connects at all.
No cookie, no tokens, just the title Upgrade: websocket. The attacker can connect to the socket directly and start listening to other people's messages, or send commands to the system from the anon, if the backend has not limited the rights.
Disadvantages of token checks
The server believes the token without checking it. What if the developer uses JWT? It can be decoded and changed to your own. Also, the server may not look at all at all on the token date and accept “extraterm”. Or you can change the algorithm from RS256 to HS256, sign the token with a famous key, and the backend will be entangled.
Preservation of the session via WS
This is an attack where the attacker will force the victim to use the known socket connection or a specific session identifier, then to intercept access to the account after the victim is authorized.
Authentication for each message
A more advanced WebSocket security design pattern, in which the verification of the rights and authenticity of the user is not once, but for each business logic frame being sent.
Bypassing authentication
The moment when the attacker has access to the data or commits actions to which his account does not have rights. The developers think that if the HTTP Handshake stage has been successful, then the entire subsequent default inside this TCP channel is safe and trusted, but this is not the case.
Control of the access channel
A mechanism that determines whether a specific connection has the right to subscribe to a specific channel/topic and send messages there.
The error of the developers is to open access to the channel only on the basis of the name that the client asks. The server believes that if the name of the channel contains UUID, then it is impossible to guess it, therefore, the verification of rights is not mandatory.
Channels are created so that users can listen to updates, but only a server or administrator should send messages there. If the rights to the channel are configured on the principle of "all or nothing", the user who subscribed to the public channel may find that the backend accepts the publication frames from him on the same channel.
IDOR via WebSocket IDs
Such a problem arises when the backend performs or returns sensitive data, blindly trusting the identifiers of the resources that the client sends extra-tie-text or binary frames, instead of verifying the rights of the session.
If the application uses ordinary serial numbers, then we simply change the number and get successful operation.
Injection attacks
Injections in WebSocket work as well as in a classic web application: the server blindly trusts the input data and executes them as a code.
XSS via WS messages
The JS malware code is transmitted inside WebSocket frames and is executed in the victim’s browser.
In standard web applications for distribution, Stored XSS needs the victim to go to a certain page, where the script will be loaded out of the database. In the WebSocket architecture, everything happens "on the fly" thanks to the Pub/Subclick model (Publish/Subscribe) or the bridgecat mechanism.
SQLi in WebSocket Parameters
Yes, it seemed that SQL injection only happens in HTTP requests, but no.
Although the mathematician and syntax of injections remain standard, the testing and operation process has unique nuances.
Most WAF only inspect the HTTP handshake phase. After the connection is established, all subsequent traffic is encapsulated in the WebSocket frames and often goes inside TLS encryption.
Command injection
The vulnerability of a critical level, as it gives RCE. A rare find for standard web applications, but it is regularly found in specialized ecosystems that use real-time protocols.
CSWSH
CSWSH or Cross-Site WebSocket Hijacking is an analogue of a CSRF attack for web sockets.
Mechanics Cross-Site WebSocket Hijacking
The attack is based on the properties of browsers and the features of the protocol specification. The victim is authorized to a legitimate and vulnerable site, enters the login / password. The server successfully authorizes it and installs a session cookie.
Without closing the tab, the user goes to the hacker’s website.
In the JS page stole a script that works automatically when downloaded. It is trying to install a WebSocket connection with a backend of the site.
The classic policy of a single source SOP would ban the script from a bad site to read answers from the legitimate one. But WebSocket SOP is not covered. The browser successfully forms a standard HTTP request Upgrade to a legitimate site and does 2 things:
1. Automatically attaches session cookies of a legitimate site, as the request goes to this domain.
2. Fills the Origin header, indicating where the request came from.
PoC and operation
To write PoC (Proof-of-Concept) we need 3 things:
• WebSocket URL: Exact endpoint address
• Type of authentication: If the application uses Cookies to authorize handshake
• Start message format: If the server requires a client to send some JSON immediately after connecting, copy it.
To demonstrate the operation:
1. Run a local server with a code that will perform the interaction
2. Simulate the victim: In the browser, open the tab and go to the local python norther
3. Analyze the conclusion