0

I am testing an application that uses both regular http rest requests and websockets. Burp cert is installed on the device I am using for the tests. I can intercept the encrypted traffic using Burp. If I change Burp options to generate a "CA-signed cert with a specific hostname" during the normal operation, all the rest requests generate a connection error (due to hostname verification failure) but the websocket keeps working fine. I am not familiar with websocket internals. Is it normal for a websocket or is it a bug?

Does the websocket protocol check for the host name only on start or is it controlled for each message? I cannot start the app with custom hostname configuration because the initial rest requests will fail and the web socket connection phase will never be reached.

Edit: These are my test steps:

  1. The app is a native Android app and all the traffic is encrypted using TLS. App uses both rest/http requests and websocket messages.

  2. I installed Burp CA to the device.

  3. I opened Burp with default settings and configured Android phone to use Burp as proxy server.
  4. I started the Android app and used it for a few minutes. I can see HTTP traffic under Proxy->HTTP history tab and websocket messages under Websocket History tab.
  5. Then without closing the app, I go to Burp Proxy->Options tab, on Proxy Listeners field select the active interface, click on edit, move to Certificate tab. On tthis window I select Generate a CA-signed vertificate with a specific hostname and set the hostname to foo.bar.

enter image description here

  1. I continue to use the app wtih this setting. From this point forward all the rest requests generate an error, both on UI and Alerts tab of Burp. But websocket keeps working. I can intercept the messages and edit them.

The questions are:

q1. is this the intended behaviour or a bug?

q2. If this is supposed to happen because the ws connection checks the certificate only at initial setup, can an active attacker mitm my web socket traffic? For example after the connection is made, if the app is presented a trusted certificate like nsa.com, can nsa read the messages?

  • 1
    "Does the websocket protocol check for the host name only on start or is it controlled for each message?" The connection is not closed between messages. It's the same connection between client and server for the entire lifetime of the socket. In human-terms, checking the hostname at the start of each message would be like making sure you're talking to the same person at the beginning of every sentence of a conversation. (Sometimes it may be useful to re-authenticate in the middle of a conversation youtube.com/watch?v=vBPG_OBgTWg but the WS protocol doesn't provide this.) – Ghedipunk Jul 3 at 21:56
  • @Ghedipunk, I added my test steps, hope this make the question more clear. – mk_ Jul 4 at 19:01
3

WebSockets are an upgrade of a HTTP request: they start with a "normal" HTTP request containing an Upgrade header field and after the server send a matching response the connection switches from HTTP to the WebSockets protocol. The WebSockets protocol itself does not contain any verification of the peer, including no verification of the hostname. Thus any such verification need to be done at the HTTP level (there is none on the client side) or in case of HTTPS/WSS at the TLS level.

Does the websocket protocol check for the host name only on start or is it controlled for each request?

Based on the information above there is no client-side hostname check for ws:// and there is only the check at the TLS level for wss://, i.e. the same check which is done for HTTPS. These checks are only done at the beginning of the TCP connection - there is no "requests" in WebSockets but there are only messages (i.e. no one response matching one request as in HTTP).

Is it normal for a websocket or is it a bug?

It is not clear what exactly is going on but it might simply that ws:// is used and not wss://. Only wss:// contains the hostname check (during TLS handshake).

  • In Burp history, the urls for captured websocket messages start with https. I think this is the same as wss. To make sure, I captured the traffic with wireshark and I did not see any cleartext traffic. – mk_ Jul 3 at 21:17
  • @mk_: yes, wss:// is essentially https:// – Steffen Ullrich Jul 3 at 21:29
  • @Ghedipunk: "...as the protocol says that the application must have access to the HTTP headers from the upgrade request...." - could you please point me to the part of the standard where it says this? And please note that this question is about checks on the client side - I'm not sure how much checking the client generated request makes on the client side. – Steffen Ullrich Jul 3 at 22:30
  • @Ghedipunk: 4.1 says what the client needs to provide not what the client has access to - of course it needs to provide the information for the request because it constructs the request. 4.2.1 is about what the server has as information - but this question is about checks done at the server side. In general the client cannot verify the server unless the server gets somehow authenticated - which is only the case with HTTPS/WSS. – Steffen Ullrich Jul 3 at 22:52
  • 1
    @SteffenUllrich Ok, I think I understood it. Since the certificate check, handshake and shared secret stuff happens when the connection is opened, changing the cert does not affect ws. Attacker does not have access to the shared secret. But the app opens a new connection for each GET request and after receiving the response connection is closed. This way when I change the cert the first GET request fails. Thanks! – mk_ Jul 4 at 20:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.