Usually, you will add script tags of 3rd party libraries like jQuery, Angular, or by some independant developers from the Content Delivery Network (CDN). If the author or the cdn gets hacked and the attacker changes the script, and includes some malicious code, then it would get downloaded from your site to the client system.

Example

You have a html page as follows

<!doctype html>
<html>
<head>
    <title>Integrity check</title>
</head>
<body>
    <script src="https://cdn.somejavascript.com"></script>
</body>
</html>

Now the author of somejavascript.com changes the script, so as to display an alert popup. Due to this, whenever the client visits your webpage, an alert box would appear.

This could well be used to log the messages and send the sensitive data too.

How to solve it

One way to solve it is to somehow check if the code has changed from what you had used, and if it has not been changed, then download it to the site.

Another way is that we can host the scripts ourselves, so even if the author updates the scrips, we can safely check it locally and replace the older local copies with newer ones. But hosting the scripts ourselves do not make it scalable, as the static content will consume our server's bandwidith to download. Instead if you host your scripts in popular CDN, or consume 3rd party scripts like jquery from CDN, then it would be already cached in user browser ( as other sites would have linked to jquery from same CDN).

Checking if the code has changed

Hash functions are good at creating a unique hash for a string. For example, if you have openssl installed in your local machine, you can run the following command to get the hash value of a string

echo -n "Techdomain" | openssl dgst -sha256 -binary | openssl base64

We get the value as

kuNvRIZywuKrmbyI1x27+OJd8YEpepvK+Ccn3p7PqsE=

Now if I tamper with the string, then the ssh value will change

echo -n "Techdomain2" | openssl dgst -sha384
SEl1U+WFhdIRIW1l7kuKUw+zf7s1s4iRolKnGJ/9EkU=

You can see that by just adding a number at the end of string, the hash value changes.

How to use sha integrity check for your files?

If you are hosting your static files in CDN, then you can generate the sha384 hash of the files. If the CDN is hacked, and somebody changes your files with malicious code, it will fail the integrity check and will not be downloaded.

Calculating hash (sha384) of a file

  1. I have created a simple script containing alert message in myscript.jsalert("Myscript is loaded");
  2. Store the contents in variablejq=`cat myscript.js`
  3. Now the contents of the jquery file is present in jq variable.
  4. Pass it through pipe as we did for stringecho -n $jq | openssl dgst -sha256 -binary | openssl base64 En5xfI3xuK4evMI+EFwqLa9e59KWIytbFszHZchgrXY=
  5. Add the integrity to your script tag<!doctype html> <html> <head> </head> <body> <script src="myscript.js" integrity="sha384-En5xfI3xuK4evMI+EFwqLa9e59KWIytbFszHZchgrXY=" crossorigin="anonymous"></script> </body> </html>
  6. Now open the html file in browser. It will display an alert popup.
  7. Edit the myscript.js file.
  8. Now if you try to open the html file in browser, it will display error message

Failed to find a valid digest in the 'integrity' attribute for resource 'http://localhost:8080/myscript.js' with computed SHA-256 integrity 'u87ADeYA1msmhPmZ6N0f9147Zb16BJiAHM1yctZ6coM='. The resource has been blocked.

As the resource has been blocked, we are sure that it will not be downloaded if the script changes.

If you are using a 3rd party library from CDN

If you are using a 3rd party library like jquery from CDN, then you do not have to calculate the sha value, as they would have already done it. Normally the vendor would provide a hash value so that you can add it in script tag.

For example, if you visit cdn.jquery.com, and try to get the link of any of the file, it will provide the following script tag

<script
src="http://code.jquery.com/jquery-3.2.1.min.js"
integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
crossorigin="anonymous"></script>

Here the hash value has been calculated by sha256 algorithm.