谷歌字体违反了内容安全策略。

70

我正在尝试使用Google字体,之前从未遇到过任何问题,但是现在当我尝试在头部添加CSS文件时,控制台会显示以下错误:

拒绝加载样式表'http://fonts.googleapis.com/css?family=Whatever',因为它违反了以下内容安全策略指令:"style-src 'self' 'unsafe-inline'"


所以你需要更改发送的CSP头文件,以允许该资源。如果您查看当前设置,您可以清楚地看到样式仅限于位置“self”,这很可能不包括“googleapis.com”。 - arkascha
我尝试使用元标签进行修改,并添加了一些在互联网上看到的东西,但我仍然无法解决这个问题... - José María
2
这与元标签无关。CSP header是一个http头,因此属于协议的一部分,而不是内容。你发送它,无论是出于故意还是意外。也许是因为你使用了某些框架,但如果没有更多细节,我们无法再说什么了。 - arkascha
哦,我正在使用Meteor JS。 - José María
3
如果你不相信看到的错误信息,可以轻松地自己检查头部信息:只需打开浏览器的开发控制台并查看基本请求的头部信息。它们将包含所说的头部信息。或者你可以使用网络嗅探器,结果相同。 - arkascha
6个回答

106

这里有两个需要修复的问题:

  • 使用https链接Google字体 (https://fonts.googleapis.com/css?family=Whatever)
  • style-src 指令中授权 https://fonts.googleapis.com,并在 font-src 指令中授权 https://fonts.gstatic.com"style-src 'self' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com"

5
“data:”用于什么? - Daniel Birowsky Popeski
2
允许使用数据URI作为内容源。 - James Spencer
34
对于其他人查看这个答案,不要复制 'unsafe-inline',因为它降低了安全性,而没有任何好处 - 这并不是字体工作所需的。它在那里的唯一原因是因为OP在他的原始代码中使用了它。使用 style-src 'self' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; - Kevin Lee
3
如果你把你的评论变成答案,我会点赞它。 - lilalinux
1
@KevinLee 实际上,如果您内联样式的话可能确实需要这样做 - 在React应用程序中非常常见。 - jBoive

69

如果你和我一样感到有点困惑,因为每个答案都只是说你需要在style-src指令中授权一个URL,而没有展示如何做到,那么这里是完整的标签:

<meta http-equiv="Content-Security-Policy" content="style-src 'self' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com;">

1
你省略的内容选项,例如default-src等,会降低安全性吗?还是说与一开始没有使用“meta csp”标签相同? - Drenai
1
允许使用 unsafe-inline 属性实际上会降低安全性。该标签可以在不使用该属性的情况下正常工作,因为它使您的应用程序更容易受到 XSS 攻击的威胁。 - Paul Razvan Berg
1
删除了"unsafe-inline"。 - Owen
1
@Owen,关于meta标签CSP的好资料真的很难找到。我不太有信心解决我的字体警告问题,因为这可能会降低其他方面的安全性:-) 我的网站是一个作品集网站,我不想在面试时被问到“你为什么这样做?” - Drenai
如果你在这里想知道为什么这对你不起作用,请同时检查HTML文件的HTTP响应头。响应头是由Web服务器设置的,如果它包含更强的条件,它将覆盖meta标签。 - Radek Matěj
显示剩余2条评论

14

有多个来源可以提供 Content-Security-Policy 的内容。

以下内容对我有效,详细说明如下。

根据您遇到的内容(css、img、font、media)源错误,您可以更改以下 URL。

<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>

希望这可以帮到你。


你的 img-src 中的 content: 是什么作用?我以前从未见过这个。 - Matija Nalis
我和你一样,搜索并修复了它。 - Manohar Reddy Poreddy

6

当使用Helmet时,以下内容可以完美运行(使用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.
      ],
    }
  })
);

2

上述组合对我没有用。我的代码是像这样从一个.scss文件导入字体的:

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

我添加了以下内容:
  • default-src 设置为 'self'。这不是必需的,但我想把其他所有东西都锁定。这个限制可能会在浏览器控制台触发错误。根据需要进行调整。我不得不添加 wss: scheme,以允许 Angular 调试器的 Web 套接字连接。
  • style-src 需要 'unsafe-inline' 关键字。我怀疑这是因为样式被打包/最小化了。
  • script-src 也需要 'unsafe-inline' 关键字。虽然我检查了下载的样式表并没有看到明显的问题,但我认为那里肯定有一些被视为脚本的东西。
  • font-src 需要 data: scheme。浏览器控制台报错无法获取 data:application/font-woff;charset=utf-8… (“font-src”)。这可能来自我的 Angular 代码中的其他位置,但对某些人可能有用。

下面是最终内容。

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

1

嗨,如果你在 server.js 中添加代码,那么应该像这样:

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))


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接