Proxy blocking websockets? How to get round - javascript

I have a websocket server running written in Python, (from https://github.com/opiate/SimpleWebSocketServer), and when I try to connect to it from my house, it works fine. However, when I try to connect to it from school, where there is a web proxy in place, it fails to connect with the error "undefined".
I believe that it is the proxy that is stopping the connection, but am not sure how to test to see if it definitely is. How can I test this, and if it is the proxy, how can I get round this?
Thanks

Many proxy servers replace the headers of HTTP requests with their own. They will remove any headers they don't understand, so when the proxy doesn't support websocket yet it will prevent any websocket handshake from working.
As a workaround you can get a TLS certificate for your website and use https and wss. This encrypts the headers and thus prevents the proxy from messing with them.
By the way: You should support TLS anyway. In todays world you no longer need a good reason to use encryption, you need a good reason not to.

Related

Validate WebSocket data

I have a WebSocket server written in javascript and send data to it from my CSharp application. Now how can I make sure that these are correct? I thought I could do something with hash values but I don't know how to do that. Does anyone have an idea or code example?
The first thing to understand is the types of WebSocket protocol/transports. WebSocket ws:// transport is basically unusable in terms of security as it uses HTTP. The wss:// protocol establishes a secure connection over TCP/HTTPS. The wss protocol, therefore, protects against man-in-the-middle attacks.
There is multiple methods to authenticate a user when setting up a WebSocket connection, and none are perfect. Since the standard WebSocket usage prevents additional headers from being set such as custom authentication headers, tried and true methods that would be used in a standard HTTPS request to verify the validity of a client can't be used.
The link here outlines some common methods to keep the client and server in sync while setting up a WebSocket connection, and still add some security so the server can keep track of what clients are opening WebSocket connections. There are a lot of workarounds listed for the server to safely receive sensitive, authentication data from the client.

Is it possible to force socket.io to use wss instead of ws, without having to change to https?

I have been trying to setup a server where users can send sign in using websockets, but I don't want to do this using ws. I want to be able turn on wss without having https. Sadly, there aren't any options to do this. And so the question is how would one do this on the client side without using https protocol.
Yes, this is possible. To do this, pass your websocket URL to the socket.io client directly, like this:
var socket = io('wss://example.com/');
Note that the reverse is not possible: while there's nothing to prevent HTTP pages from creating WSS connections, most browsers today block any WS connection from an HTTPS page to enforce the heightened security.
I would also caution that a websocket opened over WSS is still no more secure than the page it originated from. If you're using WSS for its security benefits, be advised that all that security could be for naught if an attacker overrides your page at the time that it's loaded (which HTTPS would prevent).
From the Websocket protocol specification:
A wss URI identifies a WebSocket server and resource name, and
indicates that traffic over that connection is to be protected via
TLS (including standard benefits of TLS such as data confidentiality
and integrity, and endpoint authentication).
Emphasis mine
Now you can understand the absurdity of your request: wss is https.
Of course the terminology is wrong (https is a different protocol than wss) but the bottom of the line is that both are simply the version of their respective TCP plain protocols (http and ws) over TLS.
So the answer is no.
As a matter of fact security is a complex thing.
Very experienced programmers refrain from inventing or exploring new ways and, based on the kind of question you asked, you don't appear to have much expertise this field.
So it's better to do things as best-practices say, it they say to use "https" use "https".
Starting studying security seriously (or hiring a contractor) is advised, inventing new ways to perform secure authentication is not, unless you have a PhD in abstract algebra and several years of experience in developing cryptographic schemes.

WebSocket errors when using TLS (but not without)

I have a web application that uses WebSockets to communicate between browser and server. When serving as ws, everything works as intended. If I change the protocol to wss, things mostly work as expected (the majority of messages passed from client to server, or vice versa, are received), but I occasionally one of the following errors in the Chrome console:
"Could not decode a text frame as UTF-8."
or
"Invalid frame header"
...at which point Chrome releases the connection.
I have observed this both when serving wss directly from the server (runs on .NET, uses SuperWebSocket), and in a configuration where the server uses ws and Apache's mod_proxy_wstunnel to reverse proxy to this using the wss protocol. I have also set up a simple "echo" server under the same Apache configuration, and don't observe the issue; this leads me to believe there's something funny about the data we're passing to the SuperWebSocket API. (The messages which cause the error are valid UTF-8, and again, don't see this issue when serving over ws.)
I'm at a loss for how a protocol change would cause such an issue to occur, which leads me to my question:
Are there cases where a WebSocket frame might be valid when sent without TLS but would become corrupted when sent with TLS?
Are there cases where a WebSocket frame might be valid when sent without TLS but would become corrupted when sent with TLS?
No, wss:// is the same as ws:// only that it is not using plain TCP but TCP+TLS. The WebSockets protocol itself is not aware if it is running inside a plain TCP connection or a TLS protected TCP connection. This is similar to https:// vs. http://.
But a TLS connection is more sensible to data corruption. That is if some man in the middle modifies the packets properly simple ws:// will not notice while wss:// will croak because the modification of the packet was detected. But you should get the error then at the connection level (i.e. connection broke or similar) and not at the WebSockets level like in your case (invalid frame header).
I have no idea what you are running as a WebSockets backend but I would suggest that the problem lies there. Because of the additional TLS layer wss:// might behave slightly different regarding timing and buffering of data inside the server so there might be a race conditions which happens more likely when wss:// is in use compared to ws://.

Cross browser support for Websockets in ActiveMQ

It seems clear that Apollo has support for CORS in their websockets protocol, but I can find nothing comparable in ActiveMQ. In Apollo you can add the parameter "cors_origin" to the connector description, but I can find nothing comparable in ActiveMQ's documentation. I've tried the Apollo parameter but I'm still getting connection refused errors.
I'm attempting to use the Paho Mqtt javascript client to connect. The Go clients I've written work fine over both tcp and websockets, but I've had no luck getting the js client to work.
I'm pretty sure the problem is CORS. Any ideas on how to configure ActiveMQ?
My problem with the refused connections had nothing to do with CORS. It was an authentication problem with the ActiveMQ broker (my bug, now fixed).
However, it is interesting to node that ActiveMQ appears to completely ignore the websockets "Origin" header from the browser. In other words, it will accept connections from any host (including localhost). Apollo appears to behave differently with specific CORS configuration.

Firefox OS TCPSocket API : SSL received a record that exceeded the maximum permissible length

Is it possible to turn off SSL cert verification in Firefox OS? I have Geeksphone dev preview and try to make IMAP client via TCPSocket API, but server cert is somehow invalid. I got this error:
SSL received a record that exceeded the maximum permissible length.
(Error Code: ssl_error_rx_record_too_long)
My TCPSocket initializacion is as follows
var TCPSocket = navigator.mozTCPSocket.open(
"mbp.telekom.de",
993,
{useSSL:'starttls'}
);
When I try to connect to GMail or another account, everything works OK.
Is this really server cert error or is it something else?
Thanks
Turning off the certificate verification is generally a bad idea and unlikely to help. The error says ssl_error_rx_record_too_long, and record that is too long is just too long, whether you choose to accept any certificate or not. This type of error tends to be caused by a record that is "too long for SSL/TLS", that is, some message that isn't valid SSL/TLS at all.
There are a few other problems here.
According to the documentation, TCPSocket takes a boolean for its useSSL parameter, not a string. It would seem fair to assume that somewhere in the code, there's an if (useSSL) {...}, so 'starttls' in your configuration counts as true.
Port 993 tends to be usable for IMAP over SSL (after an initial connection via SSL), not IMAP+STARTTLS on port 143 (where the same socket is upgraded to SSL/TLS after an initial plain-text connection).
The server at mbp.telekom.de doesn't accept SSL/TLS initial connections (like most IMAP servers would on that port), but accepts plain text IMAP connections upgradable to SSL/TLS via STARTTLS (which it should do on port 143 instead). This is likely to be a problem with the server configuration. This also explain why your connection works with imap.gmail.com (since it does support normal SSL/TLS connection that don't use STARTTLS on port 993, and since your {useSSL:'starttls'} in fact means {useSSL:true}).
You could in principle implement your IMAP client to upgrade the connection to SSL/TLS after using the STARTTLS command, but you'd need to be able to upgrade the same socket to SSL/TLS. I can't see anything in the TCPSocket documentation that would allow this (in the same way as SSLSocketFactory.createSocket(Socket, ...) does in Java, for example).
EDIT:
After a quick look at the TCPSocket.js source code, it seems that it does support starttls indeed, but this only makes sense with the undocumented upgradeToSecure method.
You might be able to implement IMAP+STARTTLS this way: initiate a plain IMAP connection, and then upgrade to SSL/TLS with the STARTTLS command, as described in RFC 2595. This is normally done on port 143, but since your server is (rather incorrectly) configured for this on port 993, it should work there too.
That's not a certificate error, that's an SSL protocol error. SSL packages data into 'frames' or 'records'. (pretty much packets, but at the SSL level rather than the socket level). There is a maximum length for these frames (16kb, I believe), and the server sent a frame longer than that. I couldn't tell you why: but maybe their certificate is too big and their SSL lib has bugs.

Categories