Websocket Security Analysis 101
By: Luigi Vezzoso | #pentest
Hi There!
during a CTF machine pentest on the hack the box platform, I came across a websocket connection to specific service.
I wasn’t familiar with websocket protocol and I decided to do some steps in that direction for the sake of understanding deeper the scenario. It’s quite simple to fire our pentest arsenal provided by kali or available on Internet but the couriosity taken me down in the rabbit hole.
Photo by Meghan Hessler on Unsplash
websocket protocol
Websocket protocol is described in the RFC6455 and is a way to enable a TCP-Socket-Like communication between a client (typically a browser) and a webserver.
HTTP protocol is half-duplex communication protocol where after each client request we have to wait for an answer. With websocket we can receive & send data with no specific order and without the need to re-open connections.
This way of communicating is very useful when data stream are required from server to client (e.g. stock market data stream).
The WebSocket Protocol enables two-way communication between a client running untrusted code in a controlled environment to a remote host that has opted-in to communications from that code. The security model used for this is the origin-based security model commonly used by web browsers. The protocol consists of an opening handshake followed by basic message framing, layered over TCP. The goal of this technology is to provide a mechanism for browser-based applications that need two-way communication with servers that does not rely on opening multiple HTTP connections (e.g., using XMLHttpRequest or <iframe> s and long polling).
Websocket was designed to support two-way communication over HTTP protocol (but not limited to it) to reuse existent web-server architecture to stream standard web content and web-socket data too. This permit a reuse of actual infrqastructure (web servers, proxies, etc,) to support multiple type of stream at same time.
In terms of protocol, websocket is very minimalist, and sits just over TCP to provide to browser-based or other client-server application a way to establish a long-lived connection with bidirectional flow.
Conceptually, WebSocket is really just a layer on top of TCP that does the following:
- adds a web origin-based security model for browsers
- adds an addressing and protocol naming mechanism to support multiple services on one port and multiple host names on one IP address
- layers a framing mechanism on top of TCP to get back to the IP packet mechanism that TCP is built on, but without length limits
- includes an additional closing handshake in-band that is designed to work in the presence of proxies and other intermediaries
The only relationship between websocket & HTTP protocol is that existent web-server can understand the handshake to upgrade the connection/protocol to websocket itself.
communication flow
The protocol define several messages to establishing connection. An initial handshake is needed to start the communication to the websocket. The handshake use a sintax similat to HTTP and the service behind the websocket instruct the client to change protocol “upgrade” to a different one - the websocket and not standard HTTP. Closing connection is more simple because
handhshake
Details on the client opening habdshake process could be find in the RFC6455. In that documentation are reported each required headers, how them sould be interpreted by a websocket service and how it must respond to a client.
In terms of header and other info exchanged during handshake you can here there are just some
If you want try to connect via nc or similar tool be careful on the CRLF encoding. Here the command used on my machine.
I’m not going to deep into this due the official documentation and many other valuable resources are available on Internet like:
- https://en.wikipedia.org/wiki/WebSocket
- https://btholt.github.io/complete-intro-to-realtime/websockets-backend
- https://ably.com/topic/websockets
data flow
In addion to handshaking protocol, the RFC specify a frame format with all the field used to “control” the data flow and to define which type of data is included in the payload data.
0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-------+-+-------------+-------------------------------+ |F|R|R|R| opcode|M| Payload len | Extended payload length | |I|S|S|S| (4) |A| (7) | (16/64) | |N|V|V|V| |S| | (if payload len==126/127) | | |1|2|3| |K| | | +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - + | Extended payload length continued, if payload len == 127 | + - - - - - - - - - - - - - - - +-------------------------------+ | |Masking-key, if MASK set to 1 | +-------------------------------+-------------------------------+ | Masking-key (continued) | Payload Data | +-------------------------------- - - - - - - - - - - - - - - - + : Payload Data continued ... : + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + | Payload Data continued ... | +---------------------------------------------------------------+
security consideration
Websocket [RFC]((https://www.rfc-editor.org/rfc/rfc6455) include several useful security consideration. Basically, websocket use a same origin policy security model like the browser but additional security consideration should be done:
- client connection - websocket services could be accessed from browser application (like javascript) but from other clients too… (i.e. python application) - the service cannot rely on the browser protections
- same origin - the websocket server should verify the origin of request to prevent CSFR
- client auth - websocket protocol do not define any specific way to autenticate the client so it can rely on the client auth mecanism of HTTP server like cookies, HTTP authentication mechanism, TLS auth, headers, etc.
- confidentiality & integrity - the protocol do not provide embedded confidentiality & integrity mechanism. If needed, the server shall implement a method to encrypt data or the service must use TLS.
- limit & data format -the server must implement specific limitation mechanism to prevent bad data management (i.e. frame to big, malformed data, invalid data)
attack surface
Websocket servers like others, are exposed to several types of attacks,due the many security items delegated to the service (ad to the developer) itself.
Here a list of general consideration:
- initial footprint - websocket services could be discovered in different ways: analizyng web-page source (looking for websocket connection like ws:// or wss://); capturing network traffic; reading publicly available documentation, etc.
- connection/authentication - check the limitation during connection opening: is the auth required? Specific additional header? is the Origin verified correctly? Can I spoof it?
- traffic/data – can I sniff/intercept websocket data? Are them encrypted at application level? is TLS used to protect data? Can I attack TLS connection?
- authorization - if I can connect to the service…. am I able to perform some operation or read/inject data? Do I need some authorization to perform such activities?
- input sanitization - if I can send/receive data to the websocket… can I inject invalid data? How the service respond to such invalid data?
For more deeper consideration and checklists you can rely on the owasp guideline for websocket security assessment.