Security Tip: Use Subresource Integrity on Your Resources!
[Tip#14] What is Subresource Integrity and why is it so important for securing your site?
#1 → Exposed API Keys & Passwords
#2 → Missing Authorisation
#3 → Missing Content Security Policy (CSP)
#4 → Missing Security Headers
#5 → Insecure Function Use
#6 → Outdated & Vulnerable Dependencies
#7 → Cross-Site Scripting (XSS)
#8 → Insufficient Rate Limiting
#9 → Missing Subresource Integrity (SRI)
#10 → Insufficient Input Validation & Mass-Assignment Vulnerabilities
According to the MDN Web Docs:
Subresource Integrity (SRI) is a security feature that enables browsers to verify that resources they fetch (for example, from a CDN) are delivered without unexpected manipulation. It works by allowing you to provide a cryptographic hash that a fetched resource must match.
I think that sums it up pretty well. You use SRI to ensure that the resources (scripts, styles, etc) that your site loads from external locations are what you expect them to be.
The vulnerability that SRI solves is someone compromising an external site whose script you load on your website. If someone can modify a third-party script with malware, it’ll be loaded on your site and the malware will run in your user’s browser, allowing all sorts of nefarious activities.
Let’s use the Bootstrap CSS framework as an example. Following their quick start instructions, we install Bootstrap by adding the following script tag to our page:
<script
src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"
integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p"
crossorigin="anonymous"
></script>
The integrity=
in the middle is the SRI hash. It is a SHA384 hash representation of the file the browser expects to find at the URL for the resource being loaded.
If the hash doesn’t match the file then the browser will not load it on the page. The website will probably break, but it will refuse to run any malicious code, and from a security point of view, that is significantly better.
How to Generate an SRI Hash
If the third-party resource you are including on your site doesn’t have an SRI hash, you can easily generate one using an online tool.
If we take Alpine.js as an example, their documentation says to install it in production by adding this tag:
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.12.0/dist/cdn.min.js"></script>
But there is no SRI provided by default, and therefore if unpkg.com
is compromised, your site will be too.
Using the SRI Hash tool, we can add hashes into the script include:
<script src="https://cdn.jsdelivr.net/npm/alpinejs@3.12.0/dist/cdn.min.js" integrity="sha384-cNc6Ohk6WSbK+sByRXr9COZWTDVEag1x/Qb7jg15rtdQ4eOqYCfzwQGAxvoh+FQX" crossorigin="anonymous"></script>
That’s all you need to do - there is no work needed by the provider of the resource. The browser itself will do the hashing when the resource is requested, you just need to tell it the hash you expect.
Important: You shouldn’t blindly add SRI hashes to all third-party resources, instead you need to consider if that resource is likely to be changed by the provider or not.
Both the Bootstrap and Alpine resources above are fully versioned, so they shouldn’t change and should have SRI hashes added. On the other hand, scripts includes for things like Analytics or Credit Card processing typically change over time, as their providers optimise them, so you can’t add SRI hashes without it breaking periodically. There are other controls we’ll dive into later for these situations.
Found this security tip helpful? Don't forget to subscribe to receive new Security Tips each week, and upgrade to a premium subscription to receive monthly In Depth articles, or toss a coin in the tip jar.
Reach out if you're looking for a Laravel Security Audit and Penetration Test or a budget-friendly Security Review, and find me on the various socials through Pinkary. Finally, don't forget to check out Practical Laravel Security, my interactive security course.