由于内容安全政策,Google字体未加载

时间:2019-06-19 07:32:17

标签: http-headers progressive-web-apps content-security-policy workbox

我有一个渐进式Web应用程序。我正在使用Google字体,并且在服务工作者中使用workbox

我的内容安全策略定义为:

// Omitting all the other directives
style-src 'self' https://fonts.googleapis.com 'unsafe-inline';
font-src 'self' https://fonts.gstatic.com;
connect-src 'self';

我已经按照食谱here设置了工作箱来缓存字体。代码如下:

  workbox.routing.registerRoute(
    /^https:\/\/fonts\.googleapis\.com/,
    new workbox.strategies.StaleWhileRevalidate({
      cacheName: 'google-fonts-stylesheets',
    })
  );

  workbox.routing.registerRoute(
    /^https:\/\/fonts\.gstatic\.com/,
    new workbox.strategies.CacheFirst({
      cacheName: 'google-fonts-webfonts',
      plugins: [
        new workbox.cacheableResponse.Plugin({
          statuses: [0, 200],
        }),
        new workbox.expiration.Plugin({
          maxAgeSeconds: 60 * 60 * 24 * 365,
          maxEntries: 30,
        }),
      ],
    })
  );

这里的问题是,当我尝试在浏览器(Google Chrome / Safari)或独立应用程序中加载应用程序时,无法加载字体。经过一会儿的拉扯,Chrome终于在控制台中给我一个错误:

Refused to connect to 'https://fonts.googleapis.com/css?family=Montserrat|Quicksand&display=swap' because it violates the following Content Security Policy directive: "connect-src 'self'".

Uncaught (in promise) no-response: no-response :: [{"url":"https://fonts.googleapis.com/css?family=Montserrat|Quicksand&display=swap","error":{}}]
    at o.makeRequest (https://storage.googleapis.com/workbox-cdn/releases/4.2.0/workbox-strategies.prod.js:1:3983)

GET https://fonts.googleapis.com/css?family=Montserrat|Quicksand&display=swap net::ERR_FAILED

看来我也需要在connect-src下声明Google字体。我在任何地方都没有看到提到的内容(我在Google上搜索了很多),所以我想知道这是否是一个错误,或者我是否确实需要在connect-src CSP指令中定义字体?

1 个答案:

答案 0 :(得分:0)

尽管您当前使用了Content-Security-Policy,但仍需要

connect-src 'fonts.googleapis.com'。如果我可以用您未明确要求的其他材料回答这一问题: CSP的目的是安全性;为style-src设置unsafe-inline不安全。从专用于style-src的页面上的MDN-https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/style-src

  

注意:禁止内联样式和内联脚本是CSP提供的最大的安全保障之一。但是,如果您绝对必须使用它,则可以使用一些机制。

仅以此为重点,Google的字体就无法与SRI(子资源完整性)配合使用,从而解决了安全性问题。如果安全性是值得我们尊重的一个更好的选择,那就是严格地为您的字体使用辅助服务器(除非您选择实现从CDNJS加载的对SRI友好的Web字体)。这将允许您使用Google字体实现哈希,只需确保在SERVER和字体服务器之间具有正确的CORS设置即可。我也强烈建议将您的default-src锁定为“ none”,然后定义每个以下fetch指令,如MDN在此处所述:https://developer.mozilla.org/en-US/docs/Glossary/Fetch_directive,只是请确保不要在script-src OR样式中使用unsafe-inline -src并避免不安全评估。 frame-ancestors 'none'upgrade-insecure-requests(以及使用I.E.或Edge的任何人的block-all-mixed-content),如果您决定实施SRI,则require-sri-for script style

我希望我并没有夸大我的答案,这当然可以帮助您。