Unsecure XMLHttpRequest calls from secure page - browser

in our company we need to implement a self hosted Rest Service that has to be deployed in the client workstations in order for our internal web applications to interact with them.
The web applications are in https, and we are not using, at the moment, the CSP headers.
Our concern is whether it's necessary to call the local service also in https or this can ne avoided (and so we can avoid to manage a certificate to deploy in every single workstation).
We made some trials with Chrome and Edge and it seems that the ajax calls are working also in plain http, but we would like to know if that is actually supported or not. Our internal web applications are not using, at the moment, the Content Security Policy headers.
Thank you!

On an HTTPS connection browsers will block HTTP content as mixed content, CSP will not change that. However, Chrome will allow mixed content on http://127.0.0.1 and http://localhost while Firefox will allow it on http://127.0.0.1, see note on https://developer.mozilla.org/en-US/docs/Web/Security/Mixed_content.
When you implement CSP you should include http://127.0.0.1 (or http://localhost) for the appropriate directive.

Related

How to handle http requests which are getting redirected as https using my nodejs-express app?

I am injecting some script tags in a website, with source such as http:localhost:3000/css/my-page-css.css . While its working on almost all sites, there's this particular website that is somehow sending all my http requests as https. How do I handle such a case?
I have configured an https server also on my nodejs app which listens to port 8443 and http listens to 3000. But, when I inject my script tags, they have src URLS which point to port 3000. So even if I have an https configured on my nodejs app, it won't work since it would be listening to a different port.
You are using HTTP Strict Transport Security (HSTS)
Using the securityheader.com website on your URL, or Chrome Developer tools we see the following HTTP Header is sent back by your site:
Strict-Transport-Security max-age=7889238
This HTTP Header will be configured in your webserver and is a way of your webserver telling the browser "For the next 7889238 seconds only use HTTPS on this domain. If someone tries to use HTTP (either by typing or by clicking on a link) then automatically switch HTTP to HTTPS before you send it on to the server."
This is a security feature as currently the default (if a scheme is not explicitly given) is HTTP. This allows website owners to switch the default and, even strong that that, prevents it being able to be switched back.
HSTS is set at a domain level and it is not possible to have it on for one port (e.g. 443) but not for another (e.g. 3000) - it's either on for that domain or off.
If you really want to use HTTP then you need to remove this header and remove the remembered value of this header from your browser. While chrome allows you to do this by typing chrome://net-internals/#hsts in the URL and using the delete option, the easiest way to do this is to change the max age from 7889238 to 0, and then load the website again. And then remove the header completely.
This can be especially annoying for sites like localhost where you proxy requests and inadvertently set it for that dummy host name. You should see if your node proxy server allows you to strip off that HTTP header. Some might say it would be better if browser makers ignored HSTS for localhost, however I think it would be better if developers just stopped fighting HTTPS and used that even for development environments using a self-signed certificate that is added to your local trust store. This was you can avoid problems like mixed content, and also use features that are HTTPS only (including Brotli, HTTP/2, Geo Location...etc.) while developing (though some browsers like Chrome still allow these on http://localhost).
Alternatively set up a local DNS alias for each of your dev sites and use that with or without HTTPS as appropriate for the site in question.

Forcing SSL on server level vs app level

I am pretty sure that similar questions have been asked before but I didn't manage to find any (maybe I am using the wrong terms).
I have an unsecure web app (built in Laravel). All communication between the frontend and the backend goes through http. Now, I want to switch to https. As far as I know, there are two ways I can do this.
The first is to configure the server (the one that hosts the app) to accept only https requests. If I do it this way, the communication between the client and the server will be encrypted and I won't have to change anything in my app (is this correct ?).
The second way is to configure my app to accept only https requests. If I do it this way I will have to make some changes to my application code.
Now I want to ask, are both ways equally secure ? Which way is prefered and why ?
Several things are mixed up here I'm afraid.
You can only turn on SSL on your web server (Apache, Nginx, etc). You need a server certificate, and you have to configure your web server to be able to receive https (ssl) connections. As for how exactly to do that is beyond the scope of this answer, but there are lots of tutorials you can find. You have to do this first.
When your web server is configured to support SSL, you want your web application to only be accessible over HTTPS and not plain HTTP. The purpose is that on the one hand, users who don't know the difference are still safe, and on the other hand that attackers can't downgrade a users connection to insecure plain HTTP.
Now as for how you want to enforce HTTPS for your application, you really do have two choices. You can have your web server handle plain HTTP requests and redirect them to SSL, this is an easy configuration both in Apache and Nginx. Or you can add redirects to your application to handle the scenario when it's accessed over plain HTTP and redirect your user with something like a Location header to HTTPS.
Security-wise, it doesn't really matter whether it's the webserver or the application that makes the redirect, from the client's perspective it's the same (mostly indistinguishable, actually). Choose the option that you like best. There may be for example maintainability reasons to choose one or the other. (Do you want to maintain redirection in your application code, or have your server operations add the redirect headers, etc.)
Note though, that either way, your application may still be vulnerable to an attack called SSL Stripping, and to prevent that you should always send a HSTS response header.

I want one particular page to not take https

I have this one page which has an iframe inside of which a survey page is embedded, unfortunately i'm getting "Your connection is not secure" error inside the iframe. Does anyone know how to fix this issue? By the way, the website is SSL certified, not the page i'm trying include inside the iframe. Also this is a php site not wordpress.
Thanks
You are always going to have this problem when an HTTPS page references non secured content. You options are:
move the page hosting the iframe (and its associated content) outwith HTTPS. Although, in theory a HTTP page should be able to reference HTTPS hosted javascript, CSS and images without emitting warnings, this will probably vary by browser
move the survey page into HTTPS. I am guessing that you don't host this yourself - have you contacted the provider to ask if they can provide the service via HTTPS? Have you considered using a different provider?
proxy the HTTP survey page via your server - this would require some clever configuration on the webserver or terminating the SSL connection in front of a proxy operating in reverse mode for your service and rewriting/forwarding mode for the survey. Basically, if you don't control the infrastructure this is probably a non-starter.
re-implement the survey capability within your own site.
Bear in mind that as soon as your site is exposed outside of HTTPS it becomes vulnerable to more attacks.
.htaccess is not going to help - it overrides the behaviour within a vhost - the HTTP and HTTPS sites will operate in seperate vhosts.

if i use http for part of my website and https for another part does this open up any security issues

I have a node.js app.
I have it configured to redirect everything to https from http.
but i was thinking if the extra work to make the normal pages visible on http and the logged in pages only visible via https, would be worth the effort.
does having both in my app expose any security holes?
Yes multiple, including:
Cookies are shared between the two sites unless you remember to include the "secure" attribute each time you set a cookie.
You are vulnerable to MITM attacks (e.g. replacing a "login" link on http to either keep you on http or redirect you to another site instead).
Resources need to be loaded over https on the secure site or you will get mixed security warnings. It's easy to miss this when running mixed sites.
Users will not know whether pages should be secure or not.
Can forget to renew cert and/or see cert errors but this should be more obvious if whole site is https.
Cannot use advanced security features like HSTS.
And that's just off the top of my head.
Go https everywhere and redirect all http traffic to https. Unless you've a good reason not to.
There are other benefits too (user confidence, looks more professional, small SEO boast, Google sees this as two sites, easier management of sites, Chrome will soon block access to some features like location tracking on http, cannot upgrade to HTTP/2 until you implement https... etc.).

Cross-domain error

What is a cross-domain error?
It happens when Javascript (most of the time) try to access something which it shouldn't.
Such as if you try to read another domain's cookie, that won't work. If you try to do XMLHTTP request to another domain or protocol (HTTP > HTTPS) that won't work. Because if you can do that you can hijack, steal your visitors session in other websites.
It's security feature and now it's a standard in all browser.
As I understand it, client-side tools such as Silverlight (and maybe Flash/Javascript) throw a cross-domain error when you attempt to make a connection to a server that is normally only allowed when it is made to the same domain that the page was served from (some origin policy).
A cross-domain error may be thrown when, for example, you are viewing a page on your test server when it is trying to call your live server, or when you are viewing a test page as a local file using a file:// protocol.
Try ensuring that the domain you are testing on is the same as that which the site was designed to be on. Note that Flash has the crossdomain.xml feature which specifically allow you to do cross-domain requests. Javascript also has ways to get around same origin policy, but you should be aware of the implications of what you're doing.

Resources