3/14/20

Redirect HTTP to HTTPS with JavaScript

On production environments, most websites are running under Hypertext Transfer Protocol Secure (HTTPS). This is an encrypted channel that is designed to keep the data between a client browser and server secured.  

When deploying a new website or application, we need to ensure that all traffic coming into the application is via the secure protocol (HTTPS). We should note that this is not available by default. For the most part, this is usually, and the preferred approach, a server side and/or domain registrar redirect rule.

In some cases, there are some difficulties which limits using the server side options. This can include limitations on what can be done on the cloud hosting environment or even lack of access to the domain registrar records. For those cases, we can detect the current protocol and redirect the traffic using client-side JavaScript code.  Let us review an approach by looking at this small snippet.

 

if (location.host.indexOf("localhost") < 0 

  && location.protocol.toLowerCase() !== "https:") {

    const url = `https://${location.host}`;

    location.replace(url);

}

 

 

This code snippet uses the location interface to validate the host name and protocol. If the protocol being used is not under a secured channel (HTTPS), it replaces the current location, essentially redirects, to the same host name, but it forces the secured channel.

Location Interface

The location interface is available globally and accessible via JavaScript. When using it, we could either use window.location or just location. It represents the location (URL, internet address) with all the relevant information that is visible on the browser address bar. This includes the host name and protocol information.

Host Name

The host name contains the current address or domain including port number.  We need this information to check that we are not running on localhost which is the case when we are running on development mode. We just want this rule to be enforced on production environments.

Protocol

The protocol indicates if we are using HTTP or HTTPS which is really what we are interested in finding out. We check that property, and If it does not match the secured channel, we compose a new address using the secured protocol and the host information.  Once we have the information, we are ready to execute a redirect.

Location Replace

With the new address information, we use location.replace to essentially redirect to a new location under the HTTPS protocol. It is important to use the replace method because we do not want to save the unsecured visit to our app in the session history. By using replace, we prevent the user from going back to that page via the back button. Now that we have the approach, where do we add this code?

Where to Place the Snippet

The snippet should run at the very start of the application bootstrapping process. Depending on the  application and framework being used (Angular, React, Vue etc.), we could choose to place this on the App.js file, but in most cases, we would prefer not to load our application instance yet and perform the redirect eagerly. For those cases, just include this file as a script reference on the main/index HTML page before loading the application code. Since JavaScript is single-threaded, the snippet executes first and forces the browsers to load the new secured location.

 

<head>    

 <meta http-equiv="Content-Security-Policy" 

        content="upgrade-insecure-requests">

</head>

<body>

    <div id="root"></div>    

    <script src="/js/redirect.js"></script>

    <script src="/js/app-bundle.js"></script>

 </body>

 


Content Security Policy (CSP)

We should also consider that by forcing the secured channel for our application, we should make sure that all the content (images, CSS)  be requested via the secured channel. To make sure this is done, we add the upgrade-insecure-requests policy as a meta tag in our page. This directive is evaluated to prevent the mixed-content warnings or even blocking due to a block-all-mixed-content policy enforce by browsers.

The solution to redirect HTTP to HTTPS from JavaScript is very simple but understanding the security policy implications on why we need to use a secured channel is a bit more complex. When evaluating that we need to redirect the requests, we need to consider other security concerns and validate that the redirect provides the intended results for the overall user experience.

Thanks for reading.

Originally published by ozkary.com