Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 214
Stepan Suvorov Avatar asked Mar 26 '19 15:03

Stepan Suvorov


People also ask

What can Subresource integrity prevent from happening?

Subresource Integrity is a useful security mechanism that lowers the chances of compromising end users' security if an external resource we are using – or even something we serve ourselves – gets changed with malicious code.

How do I set Subresource integrity?

Right-click a file in the File Explorer, select Send to…, and then select sri-hash . You will see the integrity value in a command box. Select the integrity value and right-click to copy it to the Clipboard. Press any key to dismiss the command box.

What does the Subresource integrity mechanism prevent in Javascript?

Subresource Integrity or SRI is a W3C recommendation to provide a method to protect website delivery. Specifically, it validates assets served by a third party, such as a content delivery network (CDN). This ensures these assets have not been compromised for hostile purposes.

How do you use integrity attributes?

Definition and Usage When using SRI, the webpage holds the hash and the server holds the file (the . js file in this case). The browser downloads the file, then checks it, 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, the file is blocked.


2 Answers

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

like image 88
Agnius Vasiliauskas Avatar answered Nov 08 '22 18:11

Agnius Vasiliauskas


I do not recommend only displaying warnings when the SRI-Hashes don't match. When see the warning as a User, it's already too late and potentially malicious scripts were executed on your machine.

However, you can implement your desired behaviour using the ServiceWorker-API and something like <script data-integrity="xxxxxxxx">. For that, you'd want to:

  1. Register a new ServiceWorker
  2. Listen to the fetch event
  3. [Client.postMessage] the targetURL to your Parent
  4. Get script integrity hash by targetURL $('script[src=event.data.targetURL]').attr('data-integrity')
    and push it into the client using Worker.postMessage
  5. hash the response using e.G. cryptojs.sha256
  6. match the hashes inside the worker
  7. If the hashes match, return the response. If they don't match, return the response and use Client.postMessage again to trigger a warning.
like image 35
Tom M Avatar answered Nov 08 '22 18:11

Tom M