Introduction to Subresource Integrity (SRI)
Summary
Subresource Integrity (SRI) is a security feature that verifies external resources using cryptographic hashes. This article explains SRI implementation, hash generation, and Cross-Origin Resource Sharing considerations.
Introduction #
Subresource Integrity (SRI) is a security feature implemented in modern web browsers to ensure that externally loaded resources have not been tampered with.
It allows you to provide a cryptographic hash that the browser uses to verify the contents of files such as JavaScript or Cascading Style Sheets (CSS) before executing or applying them.
This prevents attacks where a trusted Content Delivery Network (CDN) or third-party server is compromised and serves malicious content. If the downloaded file does not match the specified hash, the browser will refuse to load it.
What Subresource Integrity is used for #
SRI is used to secure third-party content loaded via the <script> or <link> HTML elements. When you include external resources on your website, you have no control over their content. SRI helps you ensure that these resources have not been modified by validating them against an expected cryptographic hash.
SRI protects against man-in-the-middle attacks and content injection vulnerabilities by enforcing content integrity.
Using Subresource Integrity #
You apply SRI by adding the integrity attribute to the HTML element that loads the external resource. This attribute contains a cryptographic hash of the resource’s content. You also need the crossorigin attribute if the resource is hosted on a different origin.
<script
src="https://cdn.example.com/lib.js"
integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GH9gN1UqZoltwQ2K27s9D2QeU5efU+C2sNsz8"
crossorigin="anonymous">
</script>
The browser downloads the file and calculates its hash. If the hash matches the one specified, the script runs. If not, it is blocked.
Generating SRI hashes #
You can generate the required hash using different tools. The hash must be base64-encoded and should use one of the supported algorithms:
- SHA-256
- SHA-384
- SHA-512
SRI Hash Generator #
There are several online tools like SRI Hash Generator that let you upload a file or provide a URL to generate the correct integrity hash.
OpenSSL #
You can use the openssl command-line tool to generate an SRI hash:
openssl dgst -sha384 -binary file.js | openssl base64 -A
You must prepend the generated hash with sha384- when using it in the integrity attribute.
shasum #
If you have Node.js installed, you can use the shasum tool:
shasum -a 384 file.js | awk '{print $1}' | xxd -r -p | base64
Again, you will need to prepend sha384- to the resulting string in the integrity attribute.
Using multiple hash algorithms #
You can specify multiple hash algorithms in the integrity attribute for fallback support. The browser will use the strongest supported hash.
Separate each hash with a space, e.g.:
<script
src="https://cdn.example.com/script.js"
integrity="sha384-abc123... sha512-xyz456..."
crossorigin="anonymous">
</script>
The browser attempts hashes in order of cryptographic strength (SHA-512 > SHA-384 > SHA-256). If none match, the resource is blocked. This ensures compatibility while prioritizing security.
Always include at least SHA-256 (required by spec) and prefer SHA-384 or SHA-512 for stronger security.
Implementation #
To implement SRI:
- Choose the correct file version from a trusted CDN or third-party host.
- Download the file and verify its contents or copy its URL.
- Generate the SRI hash using one of the methods above.
- Embed the file in your HTML using the
integrityattribute. - Add the
crossorigin="anonymous"attribute for cross-origin resources.
Browsers will skip verification if the integrity attribute is missing, so you must include it explicitly.
Cross-Origin Resource Sharing (CORS) #
When loading resources from another domain, the browser enforces Cross-Origin Resource Sharing (CORS) rules. For SRI to function correctly, the server must allow cross-origin requests.
The server hosting the external resource must send the Access-Control-Allow-Origin header, typically set to * or the requesting site’s origin:
Access-Control-Allow-Origin: *
Without this header, the browser will block the resource if you are using the crossorigin attribute. Learn how to read HTTP headers.
Examples #
Here is an example of a JavaScript file referenced in HTML <head> loaded using SRI:
<html>
<head>
...
<script
src="https://cdn.example.com/script.js"
integrity="sha384-KyZXEAg3QhqLMpG8r+Knujsl5+5hb7ie3pQn1gCvQ6/1kzpsL1K78/7AO69xg4xn"
crossorigin="anonymous">
</script>
...
</head>
For a script with multiple hash algorithms:
<html>
<head>
...
<script
src="https://cdn.example.com/script.js"
integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC sha512-6X6Y6Z6X6Y6Z6X6Y6Z6X6Y6Z6X6Y6Z6X6Y6Z6X6Y6Z6X6Y6Z6X6Y6Z6X6Y6Z6"
crossorigin="anonymous">
</script>
...
</head>
Example for a CSS file:
<html>
<head>
...
<link
href="https://cdn.example.com/styles.css"
rel="stylesheet"
integrity="sha384-LV2nJZgfsj1sPOHeWv4Fw5MeBi5Q/Z9jxAqFQrJH5RODNLZnKh23/NvnpxE1Uq0B"
crossorigin="anonymous">
...
</head>
Make sure to update the hash if the content of the resource changes.
FAQ's #
Most common questions and brief, easy-to-understand answers on the topic:
What is Subresource Integrity (SRI)?
Subresource Integrity (SRI) is a security feature that verifies the content of externally loaded resources using cryptographic hashes.
Can I use SRI with stylesheets and scripts?
Yes, you can use SRI with both <script> and <link> elements that load external JavaScript or CSS files.
Does SRI work with dynamically loaded scripts?
No, SRI requires the resource to remain unchanged. Dynamic scripts that vary on each request cannot be reliably verified using SRI unless you update the integrity attribute whenever the resource content changes.
How does SRI relate to Cross-Origin Resource Sharing (CORS)?
When loading resources from a different origin, the server must include the Access-Control-Allow-Origin header for SRI to work.
Can SRI be used with same-origin resources?
Yes, but it is primarily designed for external resources where you cannot control the content.
What happens if the hash does not match?
The browser will refuse to load the resource and log an error in the developer console if the hash does not match the downloaded file.
Further readings #
Sources and recommended, further resources on the topic:
- MDN Web Docs: Subresource Integrity
- MDN Web Docs: Practical implementation guide Subresource Integrity
- W3C Specification: Subresource Integrity
- Can I use: Subresource Integrity
License
Introduction to Subresource Integrity (SRI) by Jonas Jared Jacek is licensed under CC BY-SA 4.0.
This license requires that reusers give credit to the creator. It allows reusers to distribute, remix, adapt, and build upon the material in any medium or format, for noncommercial purposes only. To give credit, provide a link back to the original source, the author, and the license e.g. like this:
<p xmlns:cc="http://creativecommons.org/ns#" xmlns:dct="http://purl.org/dc/terms/"><a property="dct:title" rel="cc:attributionURL" href="https://www.ditig.com/introduction-to-subresource-integrity-sri">Introduction to Subresource Integrity (SRI)</a> by <a rel="cc:attributionURL dct:creator" property="cc:attributionName" href="https://www.j15k.com/">Jonas Jared Jacek</a> is licensed under <a href="https://creativecommons.org/licenses/by-sa/4.0/" target="_blank" rel="license noopener noreferrer">CC BY-SA 4.0</a>.</p>For more information see the Ditig legal page.