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

Google font not loading because of content security policy

我有一个渐进式网络应用程序。我正在使用 Google 字体,并且在我的 service worker 中使用 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 字体。我没有在任何地方看到它(而且我 googled 很多)所以我想知道这是一个错误还是我确实需要在 connect-src CSP 指令中定义字体?

connect-src 'fonts.googleapis.com' 将是必需的,尽管您当前 Content-Security-Policy。如果我可以用您没有特别要求的额外 material 来回答这个问题: CSP 的目的是安全;为 style-src 设置 unsafe-inline 是不安全的。来自 MDN 专用于 style-src - https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/style-src :

的页面

Note: Disallowing inline styles and inline scripts is one of the biggest security wins CSP provides. However, if you absolutely have to use it, there are a few mechanisms that will allow them.

仅关注这一点,Google 的字体不能很好地与可以解决安全问题的 SRI(子资源完整性)配合使用。如果安全是需要尊重的东西,一个更好的选择是严格为您的字体使用辅助服务器(除非您选择实现 SRI-friendly 从 CDNJS 加载的网络字体)。这将允许您使用 google 字体实现散列,只需确保在 SERVER 和字体服务器之间具有正确的 CORS 设置。我还强烈建议将您的 default-src 锁定为 'none' ,然后按照 MDN 此处的详细说明定义以下每个提取指令: https://developer.mozilla.org/en-US/docs/Glossary/Fetch_directive ,一定不要使用 unsafe-inline在 script-src OR style-src 中,同时避免 unsafe-eval。 frame-ancestors 'none'upgrade-insecure-requests(以及 block-all-mixed-content 任何使用 I.E. 或 Edge 的人)如果您决定实施 SRI,require-sri-for script style.

我希望我没有夸大我的回答,当然,它对你有帮助。