How time flies. It has been almost half a year since I started writing a simple compiler in my last article: I published Swift’s tail closure syntax in JavaScript, and I have been trying to update my article on time. However, due to the chores of work and life, I could not stick to it. A little ashamed, feeling that the plan made at the beginning of the year before is about to come true. I hope I can keep updating this article in the next period of time.

Subresource Integrity is the Integrity of subresources. If you don’t pay a lot of attention to Web security, you probably haven’t heard much about this term. It doesn’t matter if you don’t know. Next, I will discuss this content with you. I believe that after reading this article, you will have a deep understanding of what SRI is, why SRI is used, and how to practice SRI in projects if there is a need in this aspect.

What is SRI, and what problems does it solve

SRI is short for Subresource Integrity and refers to the Integrity of sub-resources. For example, the style files we introduce in the page through the link and script tags or the third party libraries we introduce are sub-resources of the page. For example:

<link rel="stylesheet" 
      href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css"  
      crossorigin="anonymous">

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js" 
        crossorigin="anonymous"></script>
Copy the code

Under normal circumstances, in order to improve the response speed and performance of web pages, we usually put these sub-resources on THE CDN. For large Internet companies, they generally have their own cloud services and basically their own CDN services. However, for small companies, they usually use the CDN function provided by cloud service providers. There is a problem here, if the resources we host on the CDN of the cloud service vendor are tampered with, it will have some impact on our business. This does not normally happen, but if our business has high security requirements, it is important to take precautions against this situation.

SRI is a solution to this problem. So what is the specific way to solve it? First of all, with a file, how do we know that the contents of the file have not been tampered with? We can do a hash of the file and then base64 encoding to generate a unique string associated with the file’s contents. If the contents of the file are changed, the string generated in the same way is not the same as the string generated in the original file. That’s how we know it’s been tampered with. If you know about blockchain, it should be easier to understand.

For each imported third-party resource, we simply add the integrity attribute to the tag, which is a string of the following form:

<script src="https://example.com/example-framework.js"
        integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"
        crossorigin="anonymous"></script>
Copy the code

Including sha384 oqVuAfXRKap7fdgcCY5uykM6 + R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC is the value of integrity, the string starting with sha384, represents the corresponding to the name of the secure hash algorithm, Sha256 and SHA512; Followed by a dash — to separate the name of the algorithm from the base64 encoded value that is subsequently generated by the algorithm; The final oqVuAfXRKap7fdgcCY5uykM6 + R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC is said to the corresponding file after calculating the string.

When the browser downloads withintegrityProperty does not immediately execute the code inside it. Or apply the styles inside. The browser will first rely onintegrityThe corresponding algorithm specified in the property value and the contents of the downloaded file calculate whether the hash value of the file is the same as the value in the tag. Only if they are the same will the corresponding style or code be executed. If the two are different, the browser will refuse to execute the corresponding code and refuse to apply the corresponding style. An error will also appear on the console alerting us that there is a problem with the currently downloaded child resource.

This allows us to use SRI to ensure that our pages do not use tampered resources downloaded from the CDN. It keeps our pages safe.

How to use SRI

The above briefly introduces the role of SRI, then how to practice it? Let’s put SRI into practice.

First we create a random index.html and add the following to it:

<script src="http://localhost:3000/test.js"
        integrity="sha384-yGduQba2SOt4PhcoqN6zsgbwhbpK8ZBguLWCSdnSRc6zY/MmfJEmBguDBXJpvXFg"
        crossorigin="anonymous"></script>
Copy the code

Then create a test.js file with the following contents:

document.write("Hello World!");
Copy the code

And then used in the local Node. Js express framework or other tools, make the test. The js can locally through http://localhost:3000/test.js access.

For the integrity property of the script tag above, we can obtain the string generated by the corresponding SHA384 algorithm by using openSSL:

cat test.js | openssl dgst -sha384 -binary | openssl base64 -A
Copy the code

In Windows, you need to use a different way to get the corresponding string.

Then open index.html in your browser and you’ll see the page say: Hello World! . If we change the contents of test.js, we will change the contents of Hello World! Remove the exclamation mark, as follows:

document.write("Hello World");
Copy the code

Then the page will be blank and no longer show Hello World. The corresponding console also displays an error, but different browsers display different error messages:

  • Chrome reported the following error:

  • Firefox displays the following error:

  • Safari reported the following error:

In any case, it will alert you to the fact that the currently downloaded subresource has a computed hash string that does not match the tag, and the browser refuses to execute the corresponding code.

There are a few other things to note here. If our test.js resource is a different source than our index.html, we also need to add crossorigin=”anonymous” to the tag to indicate that the request for the resource is shared across the source. Otherwise, the browser displays the following error:

If you are not familiar with cross-source Resource Sharing, you can refer to cross-origin Resource Sharing.

Access-control-allow-origin: * If you are using express, you can use CORS to set the header. The details are as follows:

// ...
app.use(
    cors({
        origin: "*",}));// ...
Copy the code

How do YOU use SRI in a framework

  • forVueProject by usingVue CLIWe can use this feature very easily. Through thevue.config.jsAdd a configuration to:integrity: trueSo we can see it when we build it, when we pack itindex.htmlAll resources introduced inintegrityAttribute, as shown below:
<! -... -->
<link href="/css/app.fb0c6e1c.css" rel="stylesheet"
          integrity="sha384-1Ekc46o2fTK9DVGas4xXelFNSBIzgXeLlQlipQEqYUDHkR32K9dbpIkPwq+JK6cl">
<! -... -->
<script src="/js/chunk-vendors.0691b6c2.js"
        integrity="sha384-j7EDAmdSMZbkzJnbdSJdteOHi77fyFw7j6JeGYAf4O20/zAyQq1nJ91iweLs6NDd"></script>
<script src="/js/app.290d19ae.js"
        integrity="sha384-S3skbo1aIjA4WCmQH6ltlpwMgTXWrakI5+aloQEnNKpEKRfbNyy1eq6SrV88LGOh"></script>
<! -... -->
Copy the code
  • For other frameworks, if the packaging tool usesWebpackIf so, you can use the plugin directlywebpack-subresource-integrity, please refer to the installation and use instructionshere.

Some details about Integrity

In the actual use of the process, there are many details need to pay attention to, the following to give you a further introduction.

  • The current algorithms that use compute resource file hashes are SHA256, SHA384, and SHA512, all of which are safe hashing algorithms under SHA-2.

  • Currently, MD5 and SHA-1 hash algorithms are not recommended.

  • First, there can be multiple values of Integrity, each separated by a space.

    • If multiple values use 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>
    Copy the code

    What is the secure hash algorithm that the browser is using? Or does it only take one match?

    The answer is: the browser will choose the most secure method first, and in the case of this example, the browser will choose the SHA512 algorithm for calculating the hash value. Because SHA512 is more secure than SHA384, and SHA384 is more secure than SHA256, the rest of the hashes calculated by other means are ignored. Note that if the browser calculates a different hash from sha512, the browser will assume that the resource’s hash is different from the one provided, regardless of whether the hash provided by SHA384 or SHA256 is correct. So the corresponding code will not be executed.

    • If multiple values use the same secure hash algorithm, as shown below:
    <script src="http://localhost:3000/test.js"
            crossorigin="anonymous"
            integrity=" sha384-yGduQba2SOt4PhcoqN6zsgbwhbpK8ZBguLWCSdnSRc6zY/MmfJEmBguDBXJpvXFg sha384-c+xXeW2CdZ1OuDKSrMpABg4MrVFWi3N5VKDC6CTgSRRnPr0dgprowjuFPomHgXlI sha384-E6ULLMoeKAMASZMjQ00AvU+3GzK8HPRhL/bM+P4JdcHLbNqGzU14K9ufSPJCnuex "></script>
    Copy the code

    As long as one value is the same as the browser’s calculation, the resource can be considered untampered; The content of a resource can be executed.

  • The Integrity attribute currently only supports link and script tags, but will support more subresource tags such as Audio, Embed, iframe, img, and more.

conclusion

On the Web page face resource integrity check share to the end here, I believe that if you carefully read again should have some harvest. If you have any suggestions and feedback after reading it, you can leave a comment here, or at the bottom of the article.

If you want to try it out quickly for yourself, you can refer to the SRI-Demo project, where some of the examples in this article can be put into practice. Of course, you can also write some examples to practice. After all, you will remember the relevant knowledge more firmly if you practice it yourself.

Also welcome everyone to pay attention to my public account Guanshan is not difficult, if you think this article is written well, or helpful to you, then like to share it ~

, recruiting

Dasoche, founded in 2012, is providing data analysis, marketing management, finance and transaction services for car dealers’ daily operations. As an advanced new automobile retail platform in China, we have been looking forward to redefining the industry with Internet + intelligent thinking since its birth. By linking, empowering and leading the upstream and downstream of the industrial chain, we will create an automobile circulation ecology and promote the Internet development of the automobile industry.

We belong to the financial service Division of Dasso Car Company, due to the rapid development of the business of the department; We need excellent front-end engineers to join us, and we are looking forward to working with you to do something meaningful to promote the development of the automotive industry. We achieve each other and strive for a better tomorrow together.

For more information about the company, you can browse Dasouche. For salary and benefits related to the position, you can refer to the job information. If you are very interested, you can send your resume to [email protected], or add my wechat, and note the search inside the car. I’ll take it directly to the person in charge. And can help you understand the progress of the push in time.

Reference:

  • Subresource Integrity
  • A CDN that can not XSS you: Using Subresource Integrity
  • Subresource Integrity
  • What is the best SRI hash size?