htmlsubresource-integrity

Subresource Integrity: How to show only warning but not block resource?


I would like to make a soft integration for Subresource Integrity attributes, so be sure that I did not break the application, but only to show a warning that I need to fix some places.

Is there an option to do so?


Solution

  • Secure approach

    If you need some kind of flexibility, then you should use a fallback mechanism - loading required resource from another URL. Probability that two different URL's will be hacked at the same time is a lot smaller compared to hacking just one resource. Fallback doesn't violate site security, because you must trust your known-good sources which you use in your code. If your resource is a Javascript - you can use a noncanonical-src attribute for a fallback too.

    Insecure approach

    Now, if you really, really want a user to break server and/or client security by forcing compromised resource load - at least ask a user if he/she takes responsibility by doing so. Of course this will still be a stupid thing, it's like asking "Would you like to run a virus in your computer ?". I bet nobody would like to say YES. Anyway, here is the code, which does asking these type of questions:

    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/crypto-js.min.js"></script>
      <script>
      function loadResource(path) {
        var xhttp = new XMLHttpRequest();
        xhttp.onreadystatechange = function() {
          if (this.readyState == 4 && this.status == 200) {
            var cs = CryptoJS.SHA256(this.responseText);
            if (btoa(cs) == 'NjBiMTllNWRhNmE5MjM0ZmY5MjIwNjY4YTVlYzExMjVjMTU3YTI2ODUxMzI1NjE4OGVlODBmMmQyYzhkOGQzNg==' ||
                confirm('Bootstrap is NOT the latest version 4.3.1, load anyway ?')
               ) {
              var link = document.createElement('link');
              link.rel = "stylesheet";
              link.href = path;
              document.head.appendChild(link);
            }
            else {
               var err = document.getElementById('error');
               err.title = "Component version error !";
               err.innerHTML = '&nbsp;⚠️';
            }
          }
        };
        xhttp.open("GET", path, true);
        xhttp.send();
      }
    
      loadResource(
                  //'https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css' // newest boostrap
                  'https://stackpath.bootstrapcdn.com/twitter-bootstrap/2.0.4/css/bootstrap-combined.min.css' // old legacy
                  );
      </script>
    

    DEMO