Frequently Asked Questions (FAQ)

Subresource Integrity (SRI) is a new W3C specification that allows web application developers to ensure that resources hosted on third party services such as Content Delivery Networks (CDN) are delivered without any unexpected modifications.

The W3C recommends the Subresource Integrity (SRI) as a best-practise whenever resources are loaded from a third-party source. It is a security feature that can help your site to defend against certain types of hacks and compromises. It can help you to protect your web web pages from common attacks like CSRF.

Subresource Integrity (SRI) verifies the integrity of the resource URL by using hash comparisons. It compares the hash value(Message Digest) of the resources hosted on the web server and those hosted on the third party server. What SRI does is it makes sure that the file you linked into a web page never changes. And if it does change, then the browser will detect and reject it. This is done by using file hashing.

File hashing is the process of taking a file and running it through a hash algorithm that reduces it to a short string representation, known as a hash or message digest. If the file changes, its hash value also changes. Then the browser knows something is wrong and it should not trust the file.

When using SRI, your webpage holds the hash and the server (CDN or anywhere) holds the file. The browser downloads the file, then quickly computes to make sure that it is a match with the hash in the integrity attribute. If it matches, the file is used, and if not it is blocked.

If web sites are all requesting their own copies of common libraries like the latest jQuery and if there is a common content delivery network (CDN) version of those libraries that could be used by every site, then the user would not need to keep downloading the same file again. If the users access first site, then common libraries would be downloaded and sit in their local browser cache and downloads could be skipped for each subsequent site.

Many organizations hosts their resources (scripts and CSS stylesheets) on different servers to improve the performance(front-end performance) of their websites. These group of servers is called Content Delivery Network (CDN).

However by doing so you put explicit trust in your CDN or third party service. This means that when the CDN service gets hacked, or the DNS is hijacked then your web application is hacked as well. At this stage the attacker can modify the content of a script file that is hosted on your CDN which will lead to many attacks (including CSRF). When CDN is hacked and the file is modified, it could have the injected code to steal your passwords, to mine cryptocurrency, or etc..

Therefore by implementing SRI, you can ensure that the web application is referring to a file that is actually legitimate, and if the file gets changed, your browser will not load it and the attack will fail. You can check if your browser supports the Subresource Integrity from the Can I Use website.

If you want to test your browser for subresource integrity support, please open this page.

HTTPS is used to ensure that the connection between the user's browser and the web server is encrypted. Therefore in case the content on the third party server or service is tampered with malicious code at server side by attacker, it will still be delivered to the user, irrespective of whether the connection is encrypted or not. SRI guarantees that a resource hasn't changed since it was hashed by a web author.

To use SRI, you can specify a cryptographic hash of the resource using  integrity  attribute in addition to the location of the resource in script tag.  Integrity  attribute can also be used in link tag for CSS resources. The format of the  integrity  HTML attribute is:integrity="[hash algorithm]-[base64 encoded cryptographic hash value]

The hash algorithms that can be used are;  sha256 ,  sha384  or  sha512 . Therefore to enable the Subresource integrity, simply add the integrity attribute to the script tag as shown in the below example:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js" 
    integrity="sha384-ZvpUoO/+PpLXR1lu4jmpXWu80pZlYUAfxl5NsBMWOEPSjUn/6Z/hRTt8+pR6L4N2" 
    crossorigin="anonymous">
</script>

 integrity  attribute stores the hash value of the resource URL. The hash is actually in two parts. The first is a prefix to declare which hashing algorithm to use. In this case, it’s sha384. This is followed by a dash and then the hash itself, encoded with base64. On seeing this, the browser will download jquery.min.js file. Before executing it, it will base64 decode the hash and then use the sha384 hashing algorithm to confirm that the hash matches the file it has just downloaded. If it matches, the file is executed. Otherwise, browser will reject it.

 Note:  For Subresource Integrity verification of a resource served from an origin other than the document in which it’s embedded, browsers additionally check the resource using Cross-Origin Resource Sharing (CORS) to ensure the origin serving the resource allows it to be shared with the requesting origin. If not, browsers will fail to fetch the resource.

The crossorigin attribute sets the mode of the request to an HTTP CORS Request. When the request is not on the same origin (domain), the crossorigin attribute must be present in <script> or <link> tag to check the integrity of the file. If crossorigin attribute is not present, the browser will choose to 'fail-open' which means it will load the resource as if the integrity attribute was not set in <script> or <link> tag, effectively losing all the security that SRI brings in the first place.

crossorigin attribute can take two values:  anonymous  or  use-credentials . When  crossorigin="anonymous"  is used, then no credentials are sent to the cross-origin site hosting the content. However, it will send an  Origin  HTTP header. If the server denies (by not setting the  Access-Control-Allow-Origin  HTTP header), the resource will not be used by the browser.

You can use this current web site (Hash Generator) to generate the code snippet for SRI integrity. It will compute the hash value for the resourse URL at front-end itself rather than sending the request to server to retrive the hash value. However, it will make AJAX call to fetch the content of resource URL (JS or CSS file) to compute the Hash value.

If you have hash value which you want to validate against the resource URL, you can do so by accessing Hash Validator menu. It will validate whether the given SRI hash vaule is valid or not for the resource URL.

You can also generate SRI hashes from the command-line with openssl using below command:

cat FILENAME.js | openssl dgst -sha384 -binary | openssl base64 -A

Browsers handle Subresource Integrity by doing the following:

1. When a browser sees a  <script>  or  <link>  element with an integrity attribute, the browser will first compare the script or stylesheet to the expected hash given in the integrity value before executing the script or before applying any stylesheet specified by the <link> element, .

2. If the script or stylesheet doesn’t match its associated integrity value, the browser will refuse to execute the script or apply the stylesheet changes in the webpage. It will then return a network error indicating that fetching the given resource URL failed. Sample image of the error message is given below. This was captured by intetionally altering the hash value of integrity attribute.

Error message - Failed to find a valid digest in the integrity attribute for resource