Cross browser support for Websockets in ActiveMQ - javascript

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.

Related

Webpage script connecting to two-way SSL fails

I am running a website server and a websocket server on two different ports. I'd like two-way SSL enabled on both. The website is using a gunicorn/flask app and is working fine for the two-way SSL on all browsers (desktop/mobile, except mobile Firefox). Inside that webpage is a script to connect to the websocket (python websockets server) which also has two-way SSL enabled.
This only works in desktop Firefox; anything else gives the error WebSocket connection to '<domain>:<port>' failed: WebSocket opening handshake was canceled.
On desktop Firefox, it requests user certificates for both the webpage and websocket, but like I said anything else returns the above error.
I've been scouring the internet for solutions to this and have seen some info on using proxies with certain hosting providers but I am hosting these myself and would rather not get too deep in setting up further stuff, if possible. For clarification, turning off two-way ssl and only doing server cert verification does work. It is only when the websocket asks for the clients cert that nothing happens and the error is in the console (client side, nothing shows on the server side).
Does anyone have ideas on how to keep two-way SSL for the site and websocket? Security is a major concern for this application.
This looks like the same problem as described in Cannot create WSS connection with Chrome, other browser work. The problem is that Chrome and Safari will not prompt for a client certificate for a Websockets connection. See this bug from 2013 which is still open.
If the user made already a choice which client certificate to use on the same origin it will work though. Only, an origin includes the port and your Websocket is on a different port than your website. This kind of setup can also cause other problems (like with restrictive firewalls) so it is a good idea to use a single origin and reverse proxy the Websocket from this origin. See this comment on the same bug on how to do this with nginx.

socket.io CORS access-control-allowed-origin is set to *

The security department of the company I work for is against (rightly so) Access-Control-Allow-Origin: * on the socket.io requests.
The app is not using CORS at all, this is the problem only with socket.io requests.
This is the function I am using to start socket.io after the server is ready:
exports.start = (server) => {
io = exports.socketio.socket.listen(server, {
origins: `https://${server.address().address}:*`,
rejectUnauthorized: false,
wsEngine: 'ws',
transports: ['websocket', 'polling']
});
exports.connect();
};
The issue with that is that first:
- server.address().address returns something like this ::
- I need to deploy the app on multiple servers with different addresses
- previously there was no origins property and socket.io was setting the origing to *
- when I test the solution on my local machine setting the origins to: 'https://localhost:3000' I am still getting Access-Controll-Allow-Origin: * for some socket.io requests.
Has someone already encountered this issue ?
Any help much appreciated
The problem with an automated server.address().address is that in production your server may not report the actual publicly visible server address because that public IP address may be a load balancer or a proxy or something like that and it is the public IP address (the one the browser connects to) that must be in the origins field. Your server itself can have a different IP address than what is publicly associated with your domain.
CORS issues with socket.io are caused only because socket.io by default uses http polling first and then switches over to an actual webSocket. webSocket connections all by themselves are not subject to CORS limitations. So, you can configure the client to ONLY connect with a real webSocket and then you won't have any CORS issues at all.
You can see how to use webSockets only here: Socket.io 1.x: use WebSockets only?
The only downside I know of for that is that your socket.io connection will not work in older browsers that don't support webSockets yet. For browsers that might still be in use in any meaningful quantity, that would really only be versions of IE before IE11 which looks to be about 2.5%. Some will argue that people still using IE8 are either likely less internet-savvy users or are in a very tightly controlled company and are less likely to be participating in new internet services so the relevance to a new internet service is even less than 2.5%.
If you're curious, in January 2016 Microsoft announced the dates that they would stop supporting versions of IE earlier than IE11 and all those dates have since passed (so there are no regular bug fixes for old versions of IE any more).
An alternative would be to create a config file which your server reads upon startup where whomever is deploying your server can add the public IP address or domain that should be used with CORS.

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://.

Proxy blocking websockets? How to get round

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.

Why XMPP client using strophe.js still working with out including flXHR.js?

I am using ejabberd as XMPP server,one of our project need to have a xmpp web client,for that i am referring Professional "XMPP Programming with JavaScript and jQuery" by jake moffitt i was going through chapter 3 hello world application ,here in order to make xmpp web client using strophe i have to include creating java script file such as strophe.js,flXHR.js,and strophe.flxhr.js
i have gone through example many time but failed to connect with the server,
when i checked bosh connection using localhost:5280/http-bind it is working fine!!!!!
with try and error when i try to connect with xmpp server with removing flXHR.js ,it magically got connected to xmpp server!!!!!
FLxhr.js is used for making cross domain call as per book" Flash has a strict security policy, but unlike JavaScript, it allows cross-domain
requests to be sent to domains that permit such requests."
If i bypass above FLxhr.js i have to use a proxies
i am using apache tomcat as web-app server ,i haven't setup any proxies and not included FLxhr.js file in my html page ,but still xmpp client is able to communicate with server!!
Can some one please explains me what is the reason behind this??
thanks in advance!!
It's likely that your XMPP server has CORS enabled, I know Openfire now supports this. With CORS, strophe.js is able to make a cross origin request without needing the workaround provided by flash(FLxhr.js), and also works without any server side redirects.
Cross-Origin Resource Sharing
Cross Domain AJAX for XMPP HTTP-Binding Made Easy
CORS Browser Support
If you want to quickly check to see if your XMPP server has CORS enabled, you should be able to locate a crossdomain.xml file hosted on the root of your server.
Example:
I connect Strophe to my XMPP server using the address http://192.168.0.26:7070/http-bind/.
Since I have CORS enabled, I can browse to http://192.168.0.26:7070/crossdomain.xml and the server will return an XML file.

Categories