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.