How can i fix Mixed Content issue in mqtt? - javascript

I need to connect to broker over websocket.
<script src="https://cdnjs.cloudflare.com/ajax/libs/paho-mqtt/1.0.1/mqttws31.min.js" type="text/javascript"></script>
<script>
// Create a client instance
client = new Paho.MQTT.Client("broker.hivemq.com", 8000, "" , "gokden");
// connect the client
client.connect({onSuccess:onConnect});
function onConnect(){
console.log("Connected!");
}
</script>
This is my connection code but i get this error:
mqttws31.min.js:36 Mixed Content: The page at 'karantinagunlugum.com' was loaded over HTTPS, but attempted to connect to the insecure WebSocket endpoint 'ws://broker.hivemq.com:8000/'. This request has been blocked; this endpoint must be available over WSS.

You have 2 related but separate problems here.
broker.hivemq.com doesn't support Secure MQTT over Websockets (wss://) which is why the connection is being closed after 30 seconds when you try to connect
You are trying to connect from a page that was loaded over HTTPS. Pages loaded securely can not connect to insecure resources due to the secure origin policy in the browser, this is what the second error is telling you.
You have 2 choices
Turn off HTTPS for your site. This is not a good idea.
Setup your own broker that supports Secure MQTT over Websockets.
You shouldn't really be using broker.hivemq.com for anything other than basic testing and playing, if you want to do anything serious you should be either paying for a properly hosted broker or running your own.

Related

Is it possible to create a websocket connection somehow from an HTTPS-origin javascript webpage to another cross-origin WS server?

I am developing a websocket server (let's call it WS), which is totally independent from another HTTPS server which I am also developing (let's call it Main).
WS itself is working well and I also have a command line testing tool which is written in Node.JS that can communicate with WS via websocket messages.
Main itself is also working well and I can open web pages with browsers via HTTPS without any problem.
Here's the problem:
Since command-line testing is not user-friendly to engineers that are not familiar with command lines, I want to create a "Browser Webpage Testing Tool" on Main in order to send messages to WS and receive response.
I basically used codes from here: https://blog.teamtreehouse.com/an-introduction-to-websockets#:~:text=To%20send%20a%20message%20through,binary%20data%20through%20a%20WebSocket.
However on this line
// Create a new WebSocket.
var socket = new WebSocket('ws://Ws-address');
The browser tells me "The page at 'https://MainUrl/testing-tool' was loaded over HTTPS, but attempted to connect to the insecure WebSocket endpoint 'ws://Ws-address/'. This request has been blocked; this endpoint must be available over WSS."
However the WS server is a real time application and is not intended to work over wss, rather as a requirement it must be optimized in speed as much as possible and anything else must be sacrificed.
Therefore WS will use plain ws instead of wss which has an additional tls handshake.
Is there any way to make my "Testing Tool" work?

Connect to plain socket from JavaScript [duplicate]

I have a java client and I need to rewrite it in (client-side) javascript.
I open the java Socket like this:
Socket socket = new Socket("127.0.0.1", 5015);
So I tried to use websocket in javascript:
let socket = new WebSocket("http://127.0.0.1:5015");
but here I have a js error:
Uncaught DOMException: Failed to construct 'WebSocket':
The URL's scheme must be either 'ws' or 'wss'. 'http' is not allowed.
I tried also to use the 'ws' or 'wss' protocol but the server didn't want to handshake with such protocols.
Is there a way to make such socket connection in client-side javascript or it's definitely prohibited?
The answer is a little more complicated than "no you can't do it".
Javascript in a regular web page running in a web browser cannot open a plain socket. The fundamental reason is that it is a security risk for the user. So it is intentionally not allowed.
WebSockets are the secure way to do this. In conjunction with other browser security mechanisms, they limit what a web page is permitted to connect to.
However, that is not the end of the story. It is possible (at least in theory) for trusted code to send and receive TCP and UDP traffic. The problem is that the APIs for doing this are non-standard (e.g. browser specific). In some cases are themselves implemented as 3rd-party browser extensions.
So if you really wanted to pursue this for you application, you are going to have to distribute your code as a trusted browser plugin / extension AND deal with a range of browser portability issues.
It is worth noting that there was a W3C Working Group that was trying to standardize raw socket APIs, but they have officially abandoned their efforts. Their last working draft can be found at:
https://www.w3.org/TR/tcp-udp-sockets/
Finally, there is the problem that a trusted browser extension / plugin requires the user's consent to install. Getting informed consent for something like this is difficult, given the deep and subtle security issues associated with embedding this kind of functionality in the user's browser.
No, you can't make an arbitrary TCP connection from a web page in any browser.
Web Sockets are fundamentally different than TCP sockets... they're essentially unrelated. They're a thin layer on top of HTTP along with a client API which allows bidirectional communication between a Web Socket client and a server supporting Web Sockets.
There are proxy servers you can run that allow connecting through them to make TCP connections, but this of course is a server feature and not something you can do in-browser alone.
The opening handshake is intended to be compatible with HTTP-based
server-side software and intermediaries, so that a single port can be
used by both HTTP clients talking to that server and WebSocket
clients talking to that server. To this end, the WebSocket client's
handshake is an HTTP Upgrade request:
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Origin: http://example.com
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
https://www.rfc-editor.org/rfc/rfc6455
WebSockets server must be able to handle HTTP requests!

Change Node js server (on elastic beanstalk AWS) url to HTTPS

I am trying to deploy my React js app using an AWS s3 bucket. However, I am fairly new to AWS and am having quite a difficult time. This react app communicates with a node / express server, which is hosted on an elastic beanstalk environment. I previously had the following error:
Mixed Content: The page at 'https://myReactApp.s3.amazonaws.com/index.html' was loaded over HTTPS, but requested an insecure resource 'http://myElasticBeanstalkServer.us-east-1.elasticbeanstalk.com/signIn?username=lsharon&password=test4321'. This request has been blocked; the content must be served over HTTPS.
I began the process of trying to figure out how to "convert" my EB url into HTTPS. I found lots of information about obtaining an ssl certificate. I am pretty confused on the whole process. Here is what I did:
I do have a domain name, registered through google domains. I used it to obtain an ssl certificate. My ssl certificate is verified through the AWS certificate manager console. However, I am a bit confused how this relates to my node server which is hosted on elastic beanstalk. I connect to this API using the EB url...not my domain name. How can I use my ssl certificate to secure my server url?
I did find a little info about creating a hosted zone in Route 53, as well as adding 443 ports on the load balancer in my elastic beanstalk environment. However, I got lost pretty quickly. Do I just use a 443 listener in the EB environment, or do I also need a 443 process? Could someone explain this to me? Also, relating to the Route 53 hosted zone, do I create the hosted zone using my domain name, or my API (elastic beanstalk) url? And when I create an alias, where do I route the traffic to? My domain name, my EB url, or my s3 bucket?
Currently, when I load my static web page in the browser, it renders fine and says secure. However, when I click one of my buttons (therefore sending a fetch request to my EB url), it ALSO works but changes to insecure and says my ssl is insecure.
I do apologize for all the questions. I just feel rather lost and seem to be finding lots of information but can't seem to make it work quite right. If anyone could help me out, I sure would appreciate it.
To answer your first question, you have to setup DNS somewhere, either in your Google Domains account or in Route53 depending on who you want to use as your DNS host, pointing the domain name to the load balancer.
I connect to this API using the EB url...not my domain name. How can I
use my ssl certificate to secure my server url?
You have to change your front-end application to use the domain that matches the SSL certificate when making API calls (and also use https instead of http for those API calls). There is no other option if you want the web browser to stop complaining about these security issues.
To answer your second question, SSL certificates in AWS Certificate Manager can be attached to a load balancer which will handle terminating the SSL for you. The load balancer can still communicate with the EC2 instance using non-encrypted HTTP. So all you need to do is attach the SSL certificate to the port 443 listener in the load balancer.

Connecting to WS:// websocket (unsecure) in https site

I am trying to connect to a unsecure websocket from https site.
I got an error:
VM40:164 Mixed Content: The page at
'https://username.github.io/reponame/' was loaded over HTTPS, but
attempted to connect to the insecure WebSocket endpoint
'ws://192.168.2.152:9001/mqtt'. This request has been blocked; this
endpoint must be available over WSS.
Is there any way I can connect to unsecured WebSocket from https site?
If not, I want to test my website.
I can open http://localhost:port on PC, but I need to test from android browser too. But, I cannot access it from my android device in the same network using the http://IP:port.
Any suggestions will be appreciated.

SOP violation in paho mqtt

when I am trying to use Paho MQTT javacrript with Mosquito MQTT websockets, everything works as long as the web server that I am using to serve my page and Mosquito are in the same server (same origin). However, if I try to connect to a different Mosquito instance (cross domain), Firefox throws a security error.
Problem is that the Javascript client initiates a http connection to the Mosquito web socket server and it gets upgraded to ws:// as part of negotiation. Had the initial request itself been over ws:// , SOP would not have kicked in.
I tried to connect to the second server from http://mitsuruog.github.io/what-mqtt/ and it works fine without SOP error. So, I know that the server can support ws:// . How to get this done using the Paho implementation?
Is there any way to work around this?
The issue is that I was trying to initiate an un-secure (ws:// instrad of wss://) while the page was itself loaded over https:// . This results in a mixed content error that is not explicitly reported by Firefox. Chrome prints a better warning and allows to temporarily bypass it as well.

Categories

Resources