subresource-integrity

⌘K
  1. Home
  2. SiteLint
  3. Security Rules
  4. subresource-integrity

subresource-integrity

Print this article

Description

Browsers can use Subresource Integrity (SRI), a security feature, to check that the resources they download (for instance, via a CDN), are provided without unexpected manipulation. It works by allowing you to provide a cryptographic hash that a fetched resource must match.

The rule subresource-integrity determines if integrity value is being defined for any script or link element.

Purpose

Subresource Integrity, or SRI, is a security feature that allows your browser to distinguish if the files being retrieved have been maliciously altered. The current implementation covers only the two elements outlined in the spec: <script> and <link rel="stylesheet"> elements.

An integrity value begins with at least one string, with each string including a prefix indicating a particular hash algorithm (currently the allowed prefixes are sha256, sha384, and sha512), followed by a dash and ending with the actual base64-encoded hash.

The SRI hash is generated from the file content. All you need is to read the file content and generate hash from that content. See code examples of generating SRI hash below.

The example of how to use the integrity attribute with the generated hash
<script src="https://example.com/scripts.js" integrity="sha384-i2DHGSv8BucNaLXy+qLgUBnq9L/EJOl9bg9doMjaHQGLemlwhmCMdYS+fpdurOAL" crossorigin="anonymous"></script>

In case when hash doesn’t match then the browsers that support subresource integrity will refuse to load the file because the integrity value doesn’t correspond to the actual sha384 hash of the file. You’ll see an error message logged in the developer tools console: Failed to find a valid digest in the 'integrity' attribute for resource 'https://example.com/scripts.js' with computed SHA-384 integrity '/1fX+jQ2iZOn1W5TfeCHqsgVDk+Q7emd985xOiNZ3oI='. The resource has been blocked.

How to fix it

  1. Attach a unique integrity attribute created using, e.g., SHA384. You may use the SRI Hash Generator for that purpose or check the code examples of how to generate a hash from the file using various programming languages.
  2. Webpack – you may use webpack-subresource-integrity.
  3. Angular framework – use option --subresource-integrity that enables the use of subresource integrity validation for Angular.

Code examples that helps to generate SRI hash from the file

Generating SRI hash using Go Programming Language
package sri

import (
	"crypto/sha256"
	"encoding/base64"
	"fmt"
	"io/ioutil"
)

func Generate256(file string) (string, error) {
	body, err := ioutil.ReadFile(file)

	if err != nil {
		return "", err
	}

	hash := sha256.Sum256(body)
	sha := base64.StdEncoding.EncodeToString(hash[:])

	return fmt.Sprintf("sha256-%s", sha), nil
}

// package main
//
// import (
//     "fmt"
//     "sri"
// )
//
// func main() {
//     sha, err := sri.Generate256("./src/sri.go")
//
//     if err != nil {
//         panic(err)
//     }
//
//     fmt.Println(sha)
// }
//
Generating SRI hash using JavaScript Programming Language
const crypto = require('crypto');
var const     = require('fs');

module.exports = function (file) {
    const enc  = 'utf8';
    const body = fs.readFileSync(file, { encoding: enc });
    const hash = crypto.createHash('sha256').update(body, enc);
    const sha  = hash.digest('base64');

    return `sha256-${sha}`;
}

// > const generate256 = require('./sri.js');
// undefined
// > generate256("./sri.js");
// 'sha256-U+9zwgl5Wcs2X0IzBnN/4Ri016f8lkdtvmPZuIytt8Y='
// >
Generating SRI hash using PHP Programming Language
<?php
function generate256($path) {
  $file fopen($path'r');
  $body = @fread($filefilesize($path));

  if ($body === false) {
    return '';
  }

  $hash hash('sha256'$bodytrue);
  $sha  base64_encode($hash);

  return 'sha256-$sha';
}

// php > include './sri.php';
// php > echo generate256("./sri.php");
// sha256-wdToXd37ShQdyh8ljZAJoqvPXdQEiyqGv/IBnbKkg3A=
// php >
?>
Generating SRI hash using Python Programming Language
import base64
import hashlib

def generate256(file):
    with open(file, 'r') as f:
        body = f.read()
        hash = hashlib.sha256(body).digest()
        sha  = base64.b64encode(hash).decode()
        return 'sha256-{}'.format(sha)

# Python 2.7.10 (default, Oct 14 2015, 16:09:02)
# [GCC 5.2.1 20151010] on linux2
# Type "help", "copyright", "credits" or "license" for more information.
# >>> from sri import generate256
# >>> generate256("sri.py")
# 'sha256-ZDTvTHvqQDypoPxKGrkYPNVeXQPvKqnZeAFvRZ1l+ik='
# >>>
Generating SRI hash using Ruby Programming Language
require 'digest'
require 'base64'

def generate256(file)
  body = File.read(file)
  hash = Digest::SHA256.digest(body)
  sha  = Base64.encode64(hash).strip

  "sha256-#{sha}"
end

# irb(main):001:0> require './sri'
# => true
# irb(main):002:0> generate256("sri.rb")
# => "sha256-zna8a/EB5hMXmiyjg+iSy5/Xar/+Cv0EDF1STWr+Mwo="
Generating SRI hash using Shell script
function generate256 {
  echo "sha256-`cat $1 | openssl dgst -sha256 -binary | openssl enc -base64 -A`"
}

# jmervine@laptop:~/sri $ source sri.sh
# jmervine@laptop:~/sri $ generate256 "sri.sh"
# sha256-wS2IFRvHJO0XSkrEvudmfw2nBnNz+E1o4AJ2Cf/HpZs=

Source: GitHub.

Standard

Best Practices, Security, SiteLint, Version 1.0

Was this article helpful to you? No Yes

How can we help?