How Subresource Integrity protects websites from being compromised

Notwithstanding all the advantages of fetching resources from third parties, such a solution should never be fully trusted. What if someone changes the JS code to something containing backdoors? Even worse, what if the CSS gets modified and our page ends up looking like Myspace? The answer is Subresource Integrity (SRI): a security feature that allows a browser to check if the assets you web app fetches haven’t been tampered with.

The infamous cyber attacks and their results

The reliability and security issues resulting from the use of external sources shouldn’t be neglected. Just think about the 2017 NotPetya cyberattack, which I mentioned in my article about software development security: innocent in the beginning (it all started with an installation of accounting software on a computer in Odessa), it has caused $10 billion-worth damages to large companies from all around the world, including Merck, FedEx, and Saint-Gobain.

Last year, on the other hand, we witnessed the cyberattack on Gentoo Linux, during which hackers infected the GitHub repository. The security issues and the subsequent risk of delivering compromised code sparked some serious criticism of Protonmail as well. If you’re eager to learn more about the latter case, I advise you to read the company’s response and watch this video about End-to-End Encryption.

And regardless of who is right in the Proton case and even through the above-mentioned issues go far beyond the scope of this article, you can be certain of one thing: serving users with a verified code is always a good idea.

Subresource Integrity Protection as a way of reducing the risk of a web attack

Now that we’ve covered some recent major cyberattacks, let’s see how we can prevent our website from being compromised with Subresource Integrity (SRI). The attack scenario we o protect our end-users from is as follows:

  1. Some data (e.g. JavaScript, CSS) for our application is served from an external server that we don’t control.
  2. This server is hacked and the resources it hosts are changed to malicious ones.
  3. A user visiting our website is served these infected files and gets harmed.

Now, I am going to give you an example that you can download from GitHub to play around with. The main application is written in Go and it consists of a single view that greets the user whose name’s been passed in url:

func rootHandler(w http.ResponseWriter, r *http.Request) {
name := r.URL.Path[1:]
if name == "" {
name = "Anonymous"
data := &Data{Name: name}
t, _ := template.ParseFiles("index.html")
t.Execute(w, data)

This view uses the following html template:

<!DOCTYPE html>
<title>Page for SRI presentation</title>
<h1>Hello {{ .Name }}</h1>
<p>Lorem ipsum and so on...</p>
<script src="http://localhost:5000/static/main.js" integrity="sha384-/BpPkEn/9O6UNCZimhCQwsxNaxKPttX6sUOBYLxP+OrbNTsoTRT2ln5t47YDfBIV" crossorigin="anonymous"></script>
<link rel="stylesheet" type="text/css" href="http://localhost:5000/static/main.css" integrity="sha384-foWoiFSQeHQE9INgP+tYp4b5bwiIUgxeDYSxKvGvhNL/eoaitm+jWssCQg/Dp9Bi" crossorigin="anonymous">

It’s going to be served on localhost on port 8080. The external resources will be served on localhost as well – this time on port 5000 – and consist of two files:

  1. main.js - with some js code that changes the color of the text,
  2. main.css - with some styling for background images (and since Christmas is coming, I have an Easter egg for you. There are 2 images in the media folder – count their md5 hashes and see what happens).

When loaded, the main web app should show something like this:

Subresource Integrity view

When clicked on, the title should change color. Code responsible for this (served externally) is following:

var h1 = document.getElementsByTagName("h1")[0];
h1.onclick = function(){
target =; = 'red';
function retrieveColor() { = 'black';
setTimeout(retrieveColor, 1000);

Now, let’s introduce some changes to the code. Try changing 'red' to 'green' and see what happens (remember to refresh without cache with cmd/ctrl+shift+r). We should see the following message in the console:

tester:1 Failed to find a valid digest in the 'integrity' attribute for resource 'http://localhost:5000/static/main.js' with computed SHA-256 integrity 'QGNuzku1jstZqSCGjRb107/5lFF0GTQASzYIkFIr1J4='. The resource has been blocked.

The checksum has changed leading to the blocking of the resource.

Of course, the same thing will happen if we try to use the other image as background by changing the content of CSS.

Subresource Integrity view 3


As you can see, the style hasn’t been loaded and the relevant error’s been displayed in the console. To use the other image, we need to recalculate checksums (you can use the script that is included in the repo):

$ ./ other_server/static/main.css

Replace the previous value of this attribute in the main server’s template and refresh the page. That’s what you should see now:

Subresource Integrity view 2


Final thoughts on when SRI is helpful

Subresource Integrity is a useful security mechanism that lowers the chances of compromising end users’ security if an external resource we are using – or even something we serve ourselves – gets changed with malicious code. Even if the above attack scenario does not apply to us, SRI could be useful in providing integrity when unreliable internet connections are used and some parts of our code could get changed.

Of course, this solution does not help in a situation where the attacker has access to a place from which we serve both templates and the additional resources. In this case, it’s possible for the hacker to simply change the checksum in html attributes. Nonetheless, I hope this article gives you an idea about the way Subresource Integrity helps prevent cyberattacks.

Further reading

If I managed to spark your interest in SRI, be sure to dig deeper into the subject. Here’s a short list of resources that you may find helpful:

Looking for a tech partner who pays attention to security? Check our software development process and start working on your product with us!

Navigate the changing IT landscape

Some highlighted content that we want to draw attention to to link to our other resources. It usually contains a link .