MQTT Broker username/password exposed in client/browser side configuration - frontend

I'm currently using VerneMQ as our MQTT pub/sub message broker. In our front-end side, we are using the paho-mqtt npm to connect to the broker and subscribe to topics. Data is pushed through topics by our backend services. The purpose of the UI is just to consume data through the topics.
However, in our client side configuration we are exposing our broker credentials in a way that it can be visible in the network console if someone really tried to look for it. Is there any way I can extract this away or use a more secure authentication process? If I do not provide the username/password, it cannot establish successful web socket connection.
this.mqtt.connect({
useSSL: this.mqttUseSSL,
userName: this.mqttUser, //username exposed here
password: this.mqttPwd, //password exposed here
onSuccess: () => this.onConnect(),
onFailure: (err) => this.onFailure(err)
});

I have the same doubt. I find it very insecure to expose them. As an alternative solution, it would be to use SocketIo making a kind of proxy to the frontend with the WS protocol.

Related

Why does an Insecure gRPC server still allow connections from secured clients

I can't seem to understand what's happening behind the scene, but any guidance will really be appreciated.
I have the following grpc server that is hosted on Google Cloud Run:
server.js
server.bindAsync(`0.0.0.0:${process.env.PORT}`, grpc.ServerCredentials.createInsecure(), () => { //Notice, this is insecure
server.start();
console.log('GRPC Service Started');
});
Then I was given a service url of the form:
https://test-service-abcdefghij-ue.a.run.app
Then below is a client that connects to the above server using the following code:
client.js
... new test_proto.TestAccount("test-service-abcdefghij-ue.a.run.app", grpc.credentials.createSsl()); //Notice I used createSsl instead of createInsecure()
As you can see from my client code, I used createSsl without passing a self signed certificate, yet the connection to the createInsecure server worked.
I always thought both server and client must provide same self-signed certificates.
So, why does this still work even though the server is configured to be insecure? Does it mean data will still be transmitted in plain text regardless?
Based on comments from #John Hanley posting the answer, Cloud Run does not support client SSL certificates. The client verifies the server's SSL certificate. If a client connects to a Cloud Run service using HTTP (insecure), Cloud Run will redirect the client to an HTTPS endpoint. That means the final connection is encrypted with symmetric encryption. However, encryption alone does not mean a connection is secure. Google Cloud Run also supports IAP to authorize a user's access. In other words, a secure connection requires encryption and authorization.
You can have a look at documentation.

paho-mqtt in frontend: only logged in users should be able to connect to broker

I am using the paho-mqtt library in my frontend and want to connect to my MQTT Broker which is running on my backend. I created one user account for the broker.
One way to connect to the broker is by using the username, the password and the mqtt.connect(options) function.
But this means that the username and password will be in the frontend in clear text which I have to avoid, because somebody could try to get the username and password somehow and connect to the broker - this should never happen. only users who successfully logged in should be able to connect to the broker.
How can I solve this?
Thanks for your help and all the best,
Kevin
Without knowing what broker you are using this is going to be hard to answer. I'm also assuming that when you say frontend you mean a web app and you are using the Paho Javascript client in the page to connect to the broker?
But assuming you are using a broker that supports some sort of authentication plugin/API then it will be trivial to dynamically create a username/token when the user logs into the frontend and using these to authenticate to the broker. The credentials can be passed to the page as part of the login process and used to authenticate the page, when the session expires or the user logs out then you delete these generated credentials rendering them useless.

How to implement MQTT Broker side Authorization?

I have an MQTT broker where devices are connecting to it and publishing data to the broker and I have a nodejs program that helps clients, subscribe to the topic, and receive the data they are publishing through their device.
Now my use case is to provide each client with a unique token which they have to send while connecting the MQTT broker in order to start publishing the data. And I want to validate that client token using an API and then establish a connection between the client and MQTT Broker.
I have searched for my use case but I have not found any help.
Mosquitto has an authorisation plugin API that will let you build your authentication scheme.
The doc for the API is here
You can also search GitHub for existing auth plugins e.g. https://github.com/jpmens/mosquitto-auth-plug (this plugin is no longer being developed but there are active forks)

Using and securing rabbitmq mqtt websocket and use it in browser

We need some async workers for some 1-2 min tasks and then provide the user feedback from this tasks.
The idea would be to use the rabbitmq mqtt websocket plugin and provide the user feedback when the calculations done directly in the browser.
For our "old" stack we have some api endpoints as a layer between the user (browser) and rabbitmq services which more or less act as fire and forget.
As mentioned, we now need to provide feedback where we thought it would be create to user websockets (rabbitmq mqtt plugin).
But we are wondering how do we secure the exposed websocket endpoint for each user? Currently its not a problem as we have an amqps clients with X.509.
Our new features need has public access so we can not auth the user beforehand.
Is there a way to directly and securly use the exposed endpoint or do we need a layer in between as we have now?
The RabbitMQ Web MQTT plugin supports TLS. You can then use a username / password to authenticate the user, or use client certificates.
If you need public access then there is no way to secure the endpoint. This applies to all MQTT brokers, not just RabbitMQ.
NOTE: the RabbitMQ team monitors the rabbitmq-users mailing list and only sometimes answers questions on StackOverflow.
If you use a plugable authentication source (sorry, not familiar with what RabbitMQ offers here) e.g. that stores user/password in a database. Then you can generate a short lived set of credentials for each session and the webpage can request these from the server via a REST API and then use these to authenticate the MQTT connection over WebSockets.
This means that credentials are only exposed as variables for a short time as temporary variables in the browser, which can be revoked easily as soon as the web session/actions are complete

Can ServiceStack support websockets?

Servicestack is awesome. I'm using it for my Xamarin projects (monotouch and monodroid).
Users login and authorised by ServiceStack. The session details are kept in memory i.e. userId, Ipaddress, etc.
But what would be the best way to add websocket functionality so I could push notifications to these users?
Or would it be better to just leave a regular websocket open on the client and have a small websocket server somehow read the session data (user Ipaddress) from ServiceStack in order to relay bespoke messages to client?
As an alternative to Web Sockets ServiceStack supports Server Sent Events for real-time event notifications. All the Chat Apps in the Live Demos utilizes Server Events for its real-time communication.
But it doesn't include any support for Web Sockets itself, although here's an example of using ServiceStack and SignalR in the same project.

Resources