使用 express(带头盔)使用 create-react-app 创建的应用程序时出现 CSP 错误

IT技术 javascript reactjs express create-react-app helmet.js
2021-04-10 06:29:26

我正在努力使用 Express with Helmet 来提供使用“create-react-app”创建的构建。我在资源管理器控制台中收到几个与内容安全策略相关的错误:

csp-错误

当然,它没有显示应用程序。我注意到如果在 Express 中删除 Helmet 作为中间件,它可以工作,但这不是我想要的解决方案。这是我的服务器代码:

const express = require('express');
const helmet = require('helmet');
const cors = require('cors');
const morgan = require('morgan');
const bodyParser = require('body-parser');

/**
 * Server Configuration
 */

const whitelist = [];

const app = express();

// Express Configurations

// Enable reverse proxy support in Express. This causes the the "X-Forwarded-Proto" header field to be trusted so its
// value can be used to determine the protocol. See // http://expressjs.com/api#app-settings for more details.

app.enable('trust proxy');

app.use(morgan('dev')); // Log every request to the console
app.use(helmet()); // Configure secure Headers
app.use(bodyParser.urlencoded({ extended: false })); // Enable parsing of http request body
app.use(bodyParser.json());

// CORS Configuration

const corsOptions = {
  origin: (origin, callback) => {

    if (whitelist.indexOf(origin) !== -1 || !origin) {

      callback(null, true);

    } else {

      callback(new Error('Not allowed by CORS'));

    }

  },
};

app.use(cors(corsOptions)); // Allow CORS

/**
 * Launcher method
 */

app.start = () => {

  // start node server
  const port = process.env.PORT || 3000;
  app.listen(port, () => {

    console.log(`App UI available http://localhost:${port}`);
    console.log(
      `Swagger UI available http://localhost:${port}/swagger/api-docs`,
    );

  });

};

/**
 * App Initialization
 */

function initializeApp(readyCallback) {

  readyCallback(null, app);

}

module.exports = (readyCallback) => {

  initializeApp(readyCallback);

};

谁能帮我一把?提前致谢!

3个回答

头盔维护者在这里。

发生这种情况的原因是 Helmet 默认设置的称为内容安全策略的内容。要解决您的问题,您需要配置 Helmet 的 CSP。

MDN 有一个关于 CSP 的很好的文档,我建议阅读它作为背景。之后,查看Helmet 的 README以了解如何配置其 CSP 组件。

为了针对此问题提供一些帮助,让我们看一下您看到的一个错误:

Content Security Policy: This page's settings blocked the loading of a resource at inline ("script-src").

此错误告诉script-src您 CSP指令不允许内联 JavaScript,因此它已被阻止。

这被认为是“内联”JavaScript:

<script>console.log('hello world!')</script>

然而,这不是:

<script src="/foo.js"></script>

有几种方法可以解决这个问题:

  1. 向内联添加哈希或随机数,<script>并在您的 CSP 中使用它。请参阅MDN 上的此示例以获取帮助。

  2. 重构您的应用程序以完全避免内联脚本。

  3. 更新您的 CSP 以允许不安全的内联脚本。你会做这样的事情:

    app.use(
      helmet({
        contentSecurityPolicy: {
          directives: {
            ...helmet.contentSecurityPolicy.getDefaultDirectives(),
            "script-src": ["'self'", "'unsafe-inline'", "example.com"],
          },
        },
      })
    );
    

    请注意,这被认为是不安全的。

  4. 禁用 CSP。这是最危险的选择,所以我不推荐它。

    app.use(
      helmet({
        contentSecurityPolicy: false,
      })
    );
    

您的其他错误,例如fonts.googleapis.com错误,请参考default-src,这是未指定指令时的回退。

总结:要解决您的问题,您需要告诉 Helmet 配置您的 CSP。

@NicolasMauricioCuadrado 如果它对您有用,您应该将其标记为已接受的答案。他们的回答也帮助我(安全初学者)解决了我的问题。
2021-05-28 06:29:26
很清楚,谢谢你的回答,它对我有用。唯一给我带来问题的是这行: ...helmet.contentSecurityPolicy.getDefaultDirectives() 看起来如果我传播默认指令 Helmet 会给出与重复指令相关的错误。我只是忽略了它并且它有效。
2021-06-12 06:29:26

带着同样的问题通过谷歌来到这里。我不想降低头盔中的任何安全设置,所以我更改了我的 react 构建配置。只需添加行

INLINE_RUNTIME_CHUNK=false

react 应用程序根目录中的.env然后,当您运行 npm run build以构建应用程序时,所有内联脚本都将被删除并且不再违反 CSP。这确实在第一次加载站点时添加了一个额外的初始 HTTP GET 请求,但在我看来似乎值得安全优势。

您好,这可能是一个更好的解决方案。我不确定额外的 GET 请求,你能详细说明一下吗?请。谢谢!
2021-06-08 06:29:26
非常感谢你做的这些!
2021-06-13 06:29:26
当然,我从文档create-react-app.dev/docs/production-build 中的理解是,首先添加内联的原因是将引导代码放在“index.html”中。这意味着应用程序可以在获取 index.html 后立即请求应用程序的其余部分。虽然这对于某些用例可能很重要,但我认为这对我们大多数人来说有点过早优化。
2021-06-21 06:29:26

这是第三个解决方案。将 package.json 中的构建脚本更改为以下内容:

"build": "GENERATE_SOURCEMAP=false node scripts/build.js"