Cross Domain Websocket connection causing a NS_ERROR_DOM_SECURITY_ERR - firefox

I am trying to connect to a websocket on server.domain.com from trial.domain.com
NS_ERROR_DOM_SECURITY_ERR in Firefox:
"[Exception... "Security error" code: "1000" nsresult: "0x805303e8 (NS_ERROR_DOM_SECURITY_ERR)" location: "https://trial.domain.com/home Line: 454"]"
when I am trying to make a WebSocket Connection:
try {
if (window['MozWebSocket'] !== undefined) {
socket = new MozWebSocket('ws://server.domain.com/chat');
} else {
socket = new WebSocket('ws://server.domain.com/chat');
}
trails = 0;
} catch(err){
trials++;
}

This happens by Browsers that is applying security policy that prevents of use any access to external domain that the page is hosted it self.
This occurs in scenarios when you are trying to get important connections from SSL area to non SSL and another domain (don't know if same domain will solve the problem) - that is your case. But there is more of possible scenarios of this.
This is browser related error, and it is browser who throw this error, and there is no problem with connection it self.
You have to host your WebSockets server under same domain as the http server. If that is not possible, there is few ways you can go:
If software is for inhouse use and settings in browsers can be done for use, then you can disable cross-domain security policies:
Firefox, under "about:config" set s"ecurity.fileuri.strict_origin _policy" to "false".
Chrome, run with flag "--allow-file-access-from-files"
If you have access to DNS settings of your domain, you can create sub forwarder and it will look like you are connecting to the same domain. Not sure about this option on practice, but it looks well.

Related

Is there a potential data leak when redirecting from http to https?

I have the following code in my Fastify server hosted on Heroku:
this.server.addHook('preHandler', async(req, reply) => {
const isHttps = req.headers['x-forwarded-proto'] === 'https';
if (isHttps) {
return;
}
const {
method,
url
} = req;
if (method && ['GET', 'HEAD'].includes(method)) {
const host = req.headers.host || req.hostname;
reply.redirect(301, `https://${host}${url}`);
}
});
The idea is to prevent access to the server through HTTP and force redirection to HTTPS at the application-level, since it is not possible otherwise on Heroku.
My question is: if the first request to the server via HTTP (before the redirection happens) contains sensitive information such as a username/password, wouldn't that still be "dangerous" or compromising somehow?
You have probably mis-configured something on Heroku.
Heroku domains (.herokuapp.com) are by default HTTPS enabled. The same page has a guide for custom domain SSL setup guide. Since you are talking about (username + password), I am going to assume this is a website. All you need to do is setup CORS with fastify-cors. Your website should ALWAYS be served over HTTPS.
Also you should not use the logic above. Fastify isn't meant to be used as a proxy server. The docs strongly suggest using a front-facing proxy server like nginx. With Heroku you don't need all these. It already handles this for you.
In the future you could also use Cloudflare as a "proxy server" outside Heroku.

Hosting using HTTPS and subdomain

I am a beginner in website hosting please consider if my question is too silly or this is not the right place to ask this question and direct me to the right place.
I have website (hosted on a subdomain) already running on HTTP (perfectly). I am moving to HTTPS using Let's Encrypt. I have generated the certificate, configured my application and then deployed it using AWS lightsail. I have pointed the domain name using A record, where my lightsail instance IP is pointed by my subdomain.
Problem: When ever I go to my website using the URL https://subdomain.mywebsite.com:80 it works perfectly fine with no privacy error. My HTTPS server listens on port 80. But, if I try any other URL like subdomain.mywebsite.com:80 or subdomain.mywebsite.com I get a privacy error in google chrome saying "Your connection is not private".
I think I am missing some fundamental, which I not able to understand on my own.
My application is nodejs based below is a snippet of my server
const options = {
cert: fs.readFileSync('./sslcert/fullchain.pem'),
key: fs.readFileSync('./sslcert/privkey.pem')
};
app.listen(function () {
console.log("Live");
});
https.createServer(options, app).listen(80, function() {
console.log("From HTTPS");
});
What you need is to redirect all requests to port 80 to port 443, that way browsers apply automatically https protocol.
This means that if someone uses "subdomain.mywebsite.com", it is by default http and port 80, i.e, "http://subdomain.mywebsite.com:80" and you want it to be redirected to "https://subdomain.mywebsite.com", that is listening by default on port 443.And you configure your https service on port 443, which is the standard port for https.
You have two approaches:
Do the redirection in node.js: have a look to this answer for guidance: Automatic HTTPS connection/redirect with node.js/express
Use a proxy to do the redirection:have a look to this blog post for guidance (I am not related to that blog, just did a quick google search): https://serversforhackers.com/c/redirect-http-to-https-nginx
I hope this helps. Provide some comment if you need more clarifications.

Capture HTTPS request to nonexistent server with FiddlerCore

I am trying to send a response to an HTTPS request, using FiddlerCore.
I need things to work like this: I put some fake URL in browser, like https://my_url_that_doesnt_exist.com/, then I intercept this request with FiddlerCore and respond to it with my data. But I only see a CONNECT and the host URL. I know this is because of HTTPS and Fiddler being a proxy. But is there a way to get the real full URL and be able to respond to HTTPS request, using FiddlerCore?
Also I use this code to create a root certificate if it's missing:
if (!Fiddler.CertMaker.rootCertExists())
{
if (!Fiddler.CertMaker.createRootCert())
{
throw new Exception("Could not create a certificate.");
}
}
also, I use these startup settings:
FiddlerCoreStartupFlags fcsf = FiddlerCoreStartupFlags.Default | FiddlerCoreStartupFlags.DecryptSSL|FiddlerCoreStartupFlags.AllowRemoteClients;
and CONFIG.IgnoreServerCertErrors = true;
This HTTPS request is not visible in Fiddler itself. I mean when I try some non-existent URL to which I'd like my app to respond with some custom content. It's also HTTP, not HTTPS, and Fiddler itself contains the following in response:
[Fiddler] DNS Lookup for "my_url_that_doesnt_exist.com" failed. The requested name is valid, but no data of the requested type was found
But if I use some existing HTTPS URL, like google plus or anything like that, I can see the HTTPS and all the request details.
So the question follows: How can I intercept HTTPS request to a non-existent URL and serve my content instead?
I can provide any additional details if needed.
Also makecert.exe is in the same folder where all my binaries are.
The problem is that HTTPS traffic flows through a CONNECT tunnel, and by default that secure traffic won't be sent if creating the CONNECT tunnel to the target server doesn't first succeed. Of course, if that target server doesn't exist, you end up with a DNS error in creating the tunnel, so the secure requests are never sent.
The workaround is to tell Fiddler to tell the client that the CONNECT tunnel was created, without even trying to contact the server. Do so by adding this inside the BeforeRequest handler:
if (oSession.HTTPMethodIs("CONNECT"))
{
oSession.oFlags["x-replywithtunnel"] = "GenerateTunnel";
return;
}

How do I bypass the 'ports, protocols and domains must match' CORS issue whilst in development?

I have a local site running ASP.Net MVC 3 over HTTP and HTTPS through IIS Express.
The HTTP url is http://localhost:4000 and the HTTPS is https://localhost:44301.
I'm trying to hook up the Stripe payments API but it really does not like the port, protocol and domain mismatch. I've tried using CORS to tell it to trust stripe.com but it seems that it is due to the port mismatch and I cannot figure out how to tell it to ignore that.
Adding the following header does not product any difference.
Access-Control-Allow-Origin:*
When accessing my payment page via HTTP, I get the following:
Blocked a frame with origin "https://checkout.stripe.com" from
accessing a frame with origin "http://localhost:4000". The frame
requesting access has a protocol of "https", the frame being accessed
has a protocol of "http". Protocols must match.
It gets worse when using SSL as my local SSL port is not 443.
How do I tell CORS to ignore the port mismatch whilst in development?
You can disable same origin policy while in development. Load chrome with the following argument:
--disable-web-security
https://stackoverflow.com/a/6083677/287760
Didn't the error message tell you the problem? Use HTTPs.
I still get this message my live site:
Uncaught SecurityError: Blocked a frame with origin "https://checkout.stripe.com" from accessing a frame with origin "https://getaddress.io". Protocols, domains, and ports must match.
..everything still works so I wouldn't worry about it. There's not much you can do about the domains being different.

Web Farm Framework and MVC 3: How to require Https on an Action Method?

I know you can do this:
#if !DEBUG
[RequireHttps] //apply to this action only
#endif
What if you are using Web Farm Framework where "the Controller" server receives an outside SSL 443 request, decrypts it, then forwards it to the Primary / Secondary servers using http 80 (without ssl?)
In this environment, I tried the [RequireHttps] attribute but it responded with "The page isn't redirecting properly" in Firefox. Firefox has detected that the server is redirecting the request for this address in a way that will never complete. It's recognizing it's not SSL, but because it strips off SSL, MVC won't ever see SSL attributes.
How would you rewrite certain action methods to use https in MVC 3 in a web farm? How can you do this with [RequireHttps] or do you have to cherry pick every URL in your website that requires ssl and "URL Rewrite" it?
EDIT:
I changed the controller to identify port 443 traffic and forward it to https on the web farm. I thought I could get away with only loading the SSL certs on the controller, but they need loaded on the Primary and Secondary as well (or only.)
In your action method you can check for a secure connection:
if(Request.IsSecureConnection())
{
// Secure connection logic here
}

Resources