Why You Should Not Use Protocol‑Relative URLs

Hero image for Why You Should Not Use Protocol‑Relative URLs. Image by Natalya Letunova.
Hero image for 'Why You Should Not Use Protocol‑Relative URLs.' Image by Natalya Letunova.

When you link to another website or load an external resource, you will generally specify the protocol that the browser should use within the URL. For example, if you wanted to load React via the official CDN links, it would look something like this:

<script src="https://unpkg.com/react@17/umd/react.production.min.js"></script><script src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js"></script>

The use of https:// at the beginning or src will force the visiting browser to load these resources with HTTPS. You could equally switch those out for simply http:// to load over HTTP instead (if the source allows).

This strict use of protocol can lead to mixed content problems where an HTTPS site becomes vulnerable because external resources are being called via HTTP, making the site vulnerable to onpath attacks. Generally, the browser will intervene and warn you when visiting a site that is vulnerable to these types of issues, but often by then if there is nefarious code in play it is already too late.

Traditionally, the answer to this has been to use protocolless (or Protocolrelative) URLs. These remove the protocol altogether (simply starting with a double slash: //), and allow the hosting page to determine which protocol is used. If the page itself is HTTP, then HTTP will be used, and vice versa.

Using the original React example:

<script src="//unpkg.com/react@17/umd/react.production.min.js"></script><script src="//unpkg.com/react-dom@17/umd/react-dom.production.min.js"></script>

I touched upon it earlier, but just to be clear: don't do this. When the web was a more divided mixture of HTTP and HTTPS content, this made a lot of sense. Now, it poses a very significant risk.

Whilst obviously dropping those 'http' characters saves on a few bytes of data (although honestly are you really that strapped for space?), and removes a bit of decisionmaking from the development side, it also comes with some very severe downsides too.

If you want to maintain confidence and control over your application or website, you should be specifying the protocols you are calling with rather than leaving that up to the user's browser. Really, you should also be ensuring that everything is called via HTTPS anyway; aside from the benefits Google now bestows upon secure websites (above insecure ones), having a secure platform also protects your server, files, business, data, and most importantly your users.

There aren't even any performance implications any more and with the rollout of HTTP/2, it's even faster than traditional, insecure, HTTP.

Calling resources over HTTP, or allowing for a browser to decide to make the calls without using SSL, is a bit of a dangerous game and it should be unnecessary when building a website or app in 2022. It opens you up to ManInTheMiddle or ManOnTheSide attacks, such as the attack Github experienced in 2015.

The bottom line is that you should be specifying HTTPS for all resource calls and page links, to protect yourself and your visitors.


Categories:

  1. Development
  2. Security