Google Fonts violates Content Security Policy
Asked Answered
P

6

76

I'm trying to use Google Fonts and I've never had any problems, but now when I try to add the CSS file on my header I get this error on the console:

Refused to load the stylesheet 'http://fonts.googleapis.com/css?family=Whatever' because it violates the following Content Security Policy directive: "style-src 'self' 'unsafe-inline'".

Prevention answered 29/11, 2015 at 16:13 Comment(5)
So you have to change the CSP header you send to allow that resource. If you look at the current setting you can clearly see that styles are limited to the location self which most likely does not include googleapis.com .Gondolier
I've tried modifying it using a meta tag and adding some things I've seen on the internet but I have not been able to solve the this...Lipstick
This has nothing to do with meta tags. A CSP header is an http header, so part of the protocol, not the content. You send it, be it by purpose or accidentally. Maybe because you use some framework, but we cannot say any more without you posting more details.Gondolier
Hmmmm, I'm using Meteor JSLipstick
You can easily check that header yourself if you don't believe the error message you see: just open your browsers development console and look at the headers of the basic requests done. They will contain said header. Or you use a network sniffer, comes out the same.Gondolier
C
112

There are two things to fix here:

  • Use https for the Google fonts link (https://fonts.googleapis.com/css?family=Whatever)
  • Authorize https://fonts.googleapis.com in style-src directive and https://fonts.gstatic.com in font-src directive: "style-src 'self' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com"
Conservator answered 3/1, 2016 at 11:28 Comment(5)
what is the data: for?Applicator
Allows data: URIs to be used as a content source. From developer.mozilla.org/en/docs/Web/Security/CSP/…Benjy
For others looking at this answer, don't copy over the 'unsafe-inline' as it lowers security for no good reason - it's not needed for the fonts to work. The only reason why it's there is because the OP had it in his original code. Use style-src 'self' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com;Michey
@KevinLee If you turn your comment into an answer, I'd upvote it.Staphylorrhaphy
@KevinLee actually it might very well be needed if you inline your styles - witch is very common in react applications for instance.Recitativo
P
74

If you're like me and a little confused because every answer is just saying you need to authorize a URL in a style-src directive without showing how to do it, here's the full tag:

<meta http-equiv="Content-Security-Policy" content="style-src 'self' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com;">
Piceous answered 1/11, 2017 at 10:26 Comment(7)
Do the content options you left out like default-src etc lower security, or is it the same as not having a meta csp tag in the first place?Racehorse
With the unsafe-inline attribute allowed, it actually lowers security. The tag can work fine without that, as it makes your app more vulnerable to XSS attacks.Flashy
removed the 'unsafe-inline'Piceous
I just used it as follows: <meta http-equiv="Content-Security-Policy" content="style-src 'self' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com">Constrict
@Piceous It's really difficult to find good info on meta tag csp's. I am not confident in resolving my font warning at the risk of making everything else less secure:-) My site is a portfolio site, and I don't want to be asked "why you do that??" in an interview:-)Racehorse
I was working a whole day on it and found that font-source not working on google fonts but kept that there anyway, I was using for ; style-src 'self' fonts.googleapis.com unsafe-inline' 'unsafe-eval' and it worked perfectly wellSolange
If you are here wondering why this does not work for you, check also HTTP response headers for the HTML file. The response header is set by web server and if it contains stronger condition, it will overrule the meta tag.Tortile
G
13

There are multiple sources that can be given for Content-Security-Policy.

Below has clear details, which worked for me.

Depending on which content (css, img, font, media) source error you have, you can change the URL in the below.

<html>

<head>

  <meta http-equiv="Content-Security-Policy"
    content="
      default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; 
      style-src   'self' https://fonts.googleapis.com;
      font-src    'self' data: https://fonts.gstatic.com;
      img-src     'self' data: content:;
      media-src   *;
            "
  />

 <title>My page title</title>

</head>

<body>
  some text
</body>

</html>

Hope that helps.

Guttersnipe answered 9/3, 2019 at 8:46 Comment(1)
what does content: in your img-src do? I've never seen that one beforeNovelistic
H
6

When working with Helmet, the following works perfectly (written in TypeScript):

import * as express from 'express';
import { Express } from 'express';
const helmet = require('helmet');
const expressApp: Express = express(); // Create Express instance.

expressApp.use(
  helmet.contentSecurityPolicy({
    directives: {
      fontSrc: [
        "'self'", // Default policy for specifiying valid sources for fonts loaded using "@font-face": allow all content coming from origin (without subdomains).
        'https://fonts.gstatic.com' // Google Fonts.
      ],
      styleSrc: [
        "'self'", // Default policy for valid sources for stylesheets: allow all content coming from origin (without subdomains).
        'https://fonts.googleapis.com' // Google Fonts.
      ],
    }
  })
);
Habitual answered 26/8, 2019 at 14:49 Comment(0)
P
1

The combinations above did not work for me. My code is importing the fonts from an .scss file like this:

@import url('https://fonts.googleapis.com/icon?family=Material+Icons');

I added the following:

  • default-src was set to just 'self'. This is not necessary, but I wanted everything else locked down. This restriction may trigger errors in the browser console. Adapt as needed. I had to add wss: scheme, to allow a web socket connection for the Angular debugger.
  • style-src needed the 'unsafe-inline' keyword. I suspect that it is because the style is packed/minimized.
  • script-src was also needed with the 'unsafe-inline' keyword. Although I checked the stylesheet downloaded and did not see anything obvious, I think that there must be something there that is considered a script.
  • font-src needed the data: scheme. The browser console was giving an error fetching data:application/font-woff;charset=utf-8… (“font-src”). This may be something coming from a different place in my Angular code, but it may be useful for someone.

Below the final thing.

default-src 'self' wss:;
style-src 'self' https://fonts.googleapis.com 'unsafe-inline';
script-src 'self' https://fonts.googleapis.com 'unsafe-inline';
font-src 'self' data: https://fonts.gstatic.com
Provolone answered 19/8, 2022 at 22:28 Comment(2)
'unsafe-inline' is not a good practice to follow as it mitigates XSS attacks.Perishable
True, but if you're restricting the directive to specific URLs that you trust (google in this case), the risk is mitigated.Provolone
S
0

Hi if you are adding in server.js then it should be like this

let  securityPolicy = `default-src 'self' 'unsafe-eval' 'unsafe-inline'; ` +
`script-src 'self' 'unsafe-inline' 'unsafe-eval' ` +
`img-src 'self' data:  ` +
`style-src 'self' 'unsafe-inline' 'unsafe-eval'  ` +
`font-src https://fonts.googleapis.com 'self' data:  ` 


res.header('Content-Security-Policy', res.header('Content-Security-Policy', securityPolicy))

Signorelli answered 26/1, 2023 at 3:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.