I have a progressive web app. I am using Google Fonts and I am using workbox in my service worker.
My Content Security Policy is defined as:
// Omitting all the other directives
style-src 'self' https://fonts.googleapis.com 'unsafe-inline';
font-src 'self' https://fonts.gstatic.com;
connect-src 'self';
I have set up workbox to cache the fonts by following the recipe here. The code looks like:
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,
}),
],
})
);
The problem here is that when I try to load my app, in the browser (Google Chrome / Safari) or in the standalone app, the font does not load. After many hair pulling moments, Chrome finally gave me an error in the console:
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
It appears that I need to declare google fonts under connect-src
too. I did not see that mentioned anywhere (and I googled a lot) so I wanted to know if this is a bug or I indeed need to define the font in the connect-src
CSP directive?
connect-src 'fonts.googleapis.com'
would be required, notwithstanding your current Content-Security-Policy. If I may answer this with additional material that you did not specifically request:
The purpose of CSP is Security; having unsafe-inline set for style-src is not secure. From MDN on the page dedicated to 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.
Focusing on this alone, Google’s fonts don’t play well with SRI (subresource integrity) which would solve the security issue. A better option if security is something to which one needs to pay respect would be using a secondary server strictly for your font (unless you choose to implement SRI-friendly web fonts loaded from, e.g., CDNJS). This would allow you to implement hashing with google fonts, just be sure to have the proper CORS settings between SERVER and font server. I’d also highly recommend locking down your default-src to 'none' and thereafter define each following fetch directive as detailed by MDN here: https://developer.mozilla.org/en-US/docs/Glossary/Fetch_directive , just be sure not to use unsafe-inline in script-src OR style-src and avoid unsafe-eval as well. frame-ancestors 'none'
, upgrade-insecure-requests
(as well as block-all-mixed-content
for anyone using I.E. or Edge) and if you do decide on implementing SRI, require-sri-for script style
.
I hope I haven’t overstated my answer and that, ofc, it helps you.