About Subresource Integrity (subresource integrity) If you don’t pay much attention to web security, you may not have heard of this term. I believe that after reading this article, you will be able to gain a deeper understanding of what SRI is, why you should use SRI, and how to practice using SRI in your projects if you have a need for it.
What SRI is and what it solves
SRI is shorthand for Subresource Integrity, which stands for subresource integrity. For example, for the style files we introduce in the page through the
script tags or the third-party libraries we introduce to use are the subresources of the page. For example, something like the following.
In general, in order to improve the response speed as well as the performance of web pages, we usually put these sub-resources on CDN. For large Internet companies, they will generally have their own cloud services and also basically their own CDN services. But for smaller companies, they will generally use the CDN function provided by the cloud service vendor. Here comes a problem, if the resources we host on the cloud service vendor’s CDN are tampered with in case, then it will have some impact on our business. Although this kind of thing will not happen in general, if our business has high security requirements, then it is still important to take precautionary measures against this situation.
SRI is a solution to this problem. So what is the specific way to solve it? First of all, for a file, how do we know if the content of this file has been tampered with? We can perform a
hash calculation' on the file and then generate a unique string associated with the content of the file by base64’ encoding. If the content of the file has changed, the string generated in the same way is not the same as the one generated by the original file. This way we know that the file has been tampered with. About this point should be relatively easy to understand if you know anything about blockchain.
For each introduced third-party resource, we just need to add the
integrity attribute to the corresponding tag, and the value of the
integrity attribute is a string of the form as follows.
sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC is the value of
integrity, a string starting with
sha384, which indicates the name of the corresponding secure hashing algorithm, along with
sha512; followed by a short horizontal line
-, which separates the name of the algorithm and the value of the
base64 encoding generated by this algorithm later; the last
oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC indicates the string that is generated after the corresponding file is calculated.
When a browser downloads a subresource with the
integrity attribute, it will not immediately execute the code inside; or apply the style inside. The browser will first calculate whether the hash value of the file is the same as the one in the tag based on the corresponding algorithm specified in the value of the
integrity attribute and the content of the downloaded file, and will apply the corresponding style or execute the corresponding code only if the two are the same. If the two are not the same, then the browser will refuse to execute the corresponding code, and refuse to apply the corresponding style. It will also report an error in the console, alerting us that there is a problem with the currently downloaded subresource.
In this way we ensure that our pages do not use resources downloaded from CDNs with tampered content by SRI this method. This ensures the security of our pages.
How to use SRI
The above briefly describes what SRI can do, so how do you practice it exactly? Let’s practice how to use SRI together.
First we create a random
index.html and add the following content to it.
Then create a
test.js file with the following contents.
test.js locally accessible via
http://localhost:3000/test.js using the
express framework of
Node.js or some other tool.
integrity attribute of the
script tag above, we can use the following command to obtain the corresponding
sha384 algorithm generated string via the
In case of Windows environment, you need to use another way to get the corresponding string.
index.html in your browser, you will see the page displaying:
Hello World!. If we change the content of
test.js at this time, on top of the original, remove the exclamation mark after
Hello World!, as follows.
Then this time the page is blank and no longer shows
Hello World. The corresponding console will also report an error, but the error message will be different for different browsers.
Chrome reports the following error.
Anyway, you will be reminded that the currently downloaded subresource is not the same as the one on the tag through the calculated hash string, and the browser refuses to execute the corresponding code.
Here are some more points to note, if our
test.js resource is a different source from our
index.html, then you also need to add
crossorigin="anonymous" to the tag, indicating that the request for this resource is required to be shared across the source resources. Otherwise the browser will report an error as follows.
If you don’t understand cross-origin resource sharing very well, you can refer to Cross-Origin Resource Sharing.
Of course, the corresponding server side also needs to set the corresponding response header:
Access-Control-Allow-Origin: *, if you are using
express, you can use cors to set it simply. The details are shown below
How to use SRI in the framework
- For Vue projects, we can use this feature very simply by using
Vue CLI. By adding a configuration to
integrity: true, we can see after build time that the resources introduced in the packaged
index.htmlare with the
integrityattribute, as shown below.
- For other frameworks, if the packaging tool is
Webpack, you can directly use the corresponding plugin
webpack-subresource-integrity, the installation and usage instructions can be found here.
Some details about Integrity
In the actual use process, there are still many details that need to be paid attention to, so here’s a more in-depth introduction for you.
The algorithms currently used to calculate hashes of resource files are
sha512, which are all secure hash algorithms belonging to
The algorithms for computing hash values using
SHA-1are no longer recommended.
First of all
Integrityvalues can exist more than one, using spaces to separate each value.
- If multiple values are each using different secure hashing algorithms, such as the following.
<script src="http://localhost:3000/test.js" crossorigin="anonymous" integrity=" sha256-LsK9lSOT7mZ9iEbLTm9cwaKTfuBdypNn2ID1Z9g7ZPM= sha384-yGduQba2SOt4PhcoqN6zsgbwhbpK8ZBguLWCSdnSRc6zY/MmfJEmBguDBXJpvXFg sha512-2qg2xR+0XgpsowJp3VCqWFgQalU9xPbqNTV0fdM9sV9ltHSSAcHni2Oo0Woo6aj860KvFu8S1Rdwb8oxJlMJ2Q== "></script>
So this time the browser is processed according to that safe hashing algorithm? Or is it enough to have a match?
The answer is:The browser will first choose the one with the highest security. If it is the above example, the browser will choose
sha512, the algorithm that calculates the hash value. Because the security of
sha512is greater than
sha384, and the security of
sha384is greater than
sha256, and then it will ignore the rest of the hash values calculated by other means. At this time, it should be noted that if the hash string calculated by the browser according to
sha512is different from the one provided, then regardless of whether the hash value provided by
sha256is correct, the browser will consider that the hash value calculated by this resource is not the same as the one provided. So the corresponding code will not be executed.
- If multiple values are each using the same secure hash algorithm, for example, as follows.
<script src="http://localhost:3000/test.js" crossorigin="anonymous" integrity=" sha384-yGduQba2SOt4PhcoqN6zsgbwhbpK8ZBguLWCSdnSRc6zY/MmfJEmBguDBXJpvXFg sha384-c+xXeW2CdZ1OuDKSrMpABg4MrVFWi3N5VKDC6CTgSRRnPr0dgprowjuFPomHgXlI sha384-E6ULLMoeKAMASZMjQ00AvU+3GzK8HPRhL/bM+P4JdcHLbNqGzU14K9ufSPJCnuex "></script>
Then at this time, as long as there is a value that is the same as the result calculated by the browser, then the resource can be considered untampered with; the content of the resource can be executed.
Integrityattribute only supports
scripttags for now, more tags about sub-resources will be supported later, such as: