【问题标题】:Google font not loading because of content security policy由于内容安全政策,Google 字体无法加载
【发布时间】:2019-06-19 07:32:17
【问题描述】:

我有一个渐进式网络应用程序。我正在使用 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 下声明谷歌字体。我没有看到任何地方提到过(我搜索了很多)所以我想知道这是一个错误还是我确实需要在connect-src CSP 指令中定义字体?

【问题讨论】:

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


    【解决方案1】:

    connect-src 'fonts.googleapis.com' 将是必需的,尽管您当前的内容安全策略。如果我可以用您没有特别要求的其他材料来回答这个问题: CSP 的目的是安全;为 style-src 设置 unsafe-inline 是不安全的。来自 MDN 页面上的 style-src - 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”,然后定义 MDN 在此处详述的每个以下 fetch 指令:https://developer.mozilla.org/en-US/docs/Glossary/Fetch_directive,但请确保不要在 script-src 或 style-src 中使用 unsafe-inline并避免 unsafe-eval 为好。 frame-ancestors 'none'upgrade-insecure-requests(以及 block-all-mixed-content 用于任何使用 IE 或 Edge 的人),如果您决定实施 SRI,require-sri-for script style

    我希望我的回答没有夸大其词,而且它对你有帮助。

    【讨论】:

    • 谢谢。 unsafe-inline 是一个临时设置。是的,我打算尽快删除它。一个后续问题 - 为什么在connect-src 中也没有任何关于使用谷歌字体的文档?感觉很奇怪,我是唯一面临这个问题的人,这应该是一个常见的问题
    • 好吧,connect-src 没有必要如果 Google 关心以安全的方式提供外部样式表。这是我碰巧在 Netlify 社区帮助部分的一个类似问题中回答的问题。尽管正是这种设置使我倾向于建议自托管字体。在那种特殊情况下,只需要正确的 CORS 标头即可使其主服务器从字体专用服务器获取字体。谷歌不同意其公开可用的样式表,它不会安全地提供,同时强调 CSP 的重要性。 CDNJS,我说。 -
    猜你喜欢
    • 2016-03-03
    • 1970-01-01
    • 1970-01-01
    • 2015-09-05
    • 2021-09-29
    • 2020-02-19
    • 2019-04-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多