带有 Service Worker 的 CSP

Chr*_*ris 1 content-security-policy service-worker

我想在我的站点上实现 CSP,但也有一个 Service Worker,可以缓存资源并在您离线时提供通知。我定义了以下策略:

style-src 'self'; object-src 'none'; script-src 'self' 'unsafe-inline'; worker-src 'self'; frame-ancestors 'none';
Run Code Online (Sandbox Code Playgroud)

Google 的 CSP 评估器会针对 worker 的 init 函数发出警告 - 因为内联脚本可用于做坏事 - 即使我已指定仅从我的域(worker-src 'self')加载 worker。

将此功能列入白名单的首选方法是什么?

<script>
   if (navigator.serviceWorker) {
     navigator.serviceWorker.register('/sw.js')
     .then( function (registration) {
       console.log('Success!', registration.scope);
     })
     .catch( function (error) {
       console.error('Failure!', error);
}); }
</script>
Run Code Online (Sandbox Code Playgroud)

jro*_*jro 7

即使您限制了加载 worker 的能力,内联脚本标签也可用于执行XSS 攻击

CSP通过阻止所有内联脚本来防止 XSS。有了一个'unsafe-inline'指令,CSP 的有效性就会大大降低,因此最好使用其他方法。

方法一:分离文件

您可以将脚本放入另一个文件中,例如 loadWorker.js,并通过常规脚本标签包含它:

loadWorker.js:

if (navigator.serviceWorker) {
  navigator.serviceWorker.register('/sw.js')
    .then(function (registration) {
      console.log('Success!', registration.scope);
    })
    .catch(function (error) {
      console.error('Failure!', error);
    });
}
Run Code Online (Sandbox Code Playgroud)

您的 html 文件:

<script src="./loadWorker.js"></script>
Run Code Online (Sandbox Code Playgroud)

方法 2:使用哈希

如果您明确允许使用 hash 的特定脚本,CSP 允许内联脚本。

以下 js 的哈希值

   if (navigator.serviceWorker) {
     navigator.serviceWorker.register('/sw.js')
     .then( function (registration) {
       console.log('Success!', registration.scope);
     })
     .catch( function (error) {
       console.error('Failure!', error);
}); }
Run Code Online (Sandbox Code Playgroud)

'sha256-vTdjucjBZWvbihWowJ2vrpjYlv4kalHHBIgd7vBr124='

将它添加到您的CSP头,像这样:Content-Security-Policy: script-src 'sha256-vTdjucjBZWvbihWowJ2vrpjYlv4kalHHBIgd7vBr124='

注意:对代码的任何更改,包括空格都会更改哈希。您将需要重新计算散列并替换您的标头。这种方法比较麻烦,不推荐