
Why You Should Not Use Protocol‑Relative URLs

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 on‑path 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 protocol‑less (or Protocol‑relative) 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 decision‑making 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 Man‑In‑The‑Middle or Man‑On‑The‑Side 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:
Related Articles

Can I Learn Front‑End Development in 2 Months? Where to Find Jobs in Web Development. Where to Find Jobs in Web Development

JavaScript Essentials for Freelance Web Developers. JavaScript Essentials for Freelance Web Developers

Building Custom Hooks in React. Building Custom Hooks in React

Optional Chaining in JavaScript (?.). Optional Chaining in JavaScript (
?.)
Escaping and Unescaping Special Characters in JavaScript. Escaping and Unescaping Special Characters in JavaScript

DOMContentLoaded vs. load in JavaScript. DOMContentLoadedvs.loadin JavaScript
Reverse an Array in JavaScript. Reverse an Array in JavaScript

Tagged Template Literals in JavaScript. Tagged Template Literals in JavaScript

Understanding the Difference Between 'Indexes' and 'Indices'. Understanding the Difference Between 'Indexes' and 'Indices'

The Difference Between JavaScript Callbacks and Promises. The Difference Between JavaScript Callbacks and Promises

Validating Parentheses Input Using TypeScript. Validating Parentheses Input Using TypeScript