子资源完整性:如何仅显示警告而不阻止资源?

时间:2019-03-26 15:08:18

标签: html subresource-integrity

我想对 Subresource Integrity 属性进行软集成,因此请确保我没有破坏应用程序,仅是为了显示警告。 ,我需要修复一些地方。

是否可以选择这样做?

2 个答案:

答案 0 :(得分:4)

安全方法

如果需要某种灵活性,则应使用fallback mechanism-从另一个URL加载所需的资源。与仅入侵一种资源相比,将同时入侵两个不同的URL的可能性要小得多。后备不会违反网站安全性,因为您必须信任您在代码中使用的已知有效资源。如果您的资源是Javascript-您也可以使用noncanonical-src属性作为后备。

不安全的方法

现在,如果您真的希望用户通过强迫资源负载受损来破坏服务器和/或客户端的安全性,请至少询问用户是否为此承担了责任。当然,这仍然是愚蠢的事情,就像问“ 您要在计算机上运行病毒吗?”。我敢打赌,没人愿意说是。无论如何,这是代码,它确实会询问以下类型的问题:

<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

答案 1 :(得分:1)

我不建议仅在SRI哈希不匹配时显示警告。当以用户身份看到警告时,已经太迟了,并且可能在您的计算机上执行了潜在的恶意脚本。

但是,您可以使用ServiceWorker-API和类似<script data-integrity="xxxxxxxx">之类的东西来实现所需的行为。为此,您需要:

  1. 注册新的ServiceWorker
  2. 收听fetch事件
  3. [Client.postMessage]指向您父母的targetURL
  4. 通过targetURL $('script[src=event.data.targetURL]').attr('data-integrity')获取脚本完整性哈希
    并使用Worker.postMessage
  5. 将其推送到客户端
  6. 使用e.G.哈希响应cryptojs.sha256
  7. 匹配工作人员内部的哈希
  8. 如果哈希匹配,则返回响应。如果它们不匹配,请返回响应并再次使用Client.postMessage来触发警告。