连接到我的 api 时出现电子内容安全策略错误

问题描述 投票:0回答:6

创建一个简单的电子应用程序模板。我想对我的 api 执行获取请求,但不断被内容安全策略错误阻止,而且我不知道如何修复它们。

拒绝连接到“https://api.myapp.com/”,因为它违反了 以下内容安全策略指令:“default-src 'self' 'unsafe-inline' 数据:”。请注意,'connect-src' 没有明确显示 设置,因此“default-src”用作后备。

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Security-Policy" content="default-src 'self' 'unsafe-eval' ">
    <meta charset="UTF-8">
  </head>
  <body>
    <div id="root"></div>
  </body>
</html>

app.js

 const handleSubmit = async () => {
    const response = await fetch("https://api.myapp.com/books", {
      method: "GET",
      headers: {
        "Content-Type": "application/json",
      },
    });
    return response.json();
  };

我尝试将 api 地址添加到现有策略中,并添加其他策略,但没有任何效果。

html node.js webpack electron content-security-policy
6个回答
18
投票

我找到了这个问题的答案。看来 Webpack 对开发者模式使用了默认的内容安全策略,可以在 package.json 中覆盖它。

取自 webpack WebpackPluginRendererConfig

/**
     * Sets the [`Content-Security-Policy` header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy)
     * for the Webpack development server.
     *
     * Normally you would want to only specify this as a `<meta>` tag. However, in development mode,
     * the Webpack plugin uses the `devtool: eval-source-map` source map setting for efficiency
     * purposes. This requires the `'unsafe-eval'` source for the `script-src` directive that wouldn't
     * normally be recommended to use. If this value is set, make sure that you keep this
     * directive-source pair intact if you want to use source maps.
     *
     * Default: `default-src 'self' 'unsafe-inline' data:;`
     * `script-src 'self' 'unsafe-eval' 'unsafe-inline' data:`
     */
    devContentSecurityPolicy?: string;

通过在 package.json 中设置 devContentSecurityPolicy,我可以设置自己的内容安全策略。

"plugins": [
        [
          "@electron-forge/plugin-webpack",
          {
            "mainConfig": "./webpack.main.config.js",
            "devContentSecurityPolicy": "connect-src 'self' https://api.myapp.com 'unsafe-eval'",
            "renderer": {
              "config": "./webpack.renderer.config.js",
              "entryPoints": [
                {
                  "html": "./src/index.html",
                  "js": "./src/renderer.ts",
                  "name": "main_window"
                }
              ]
            }
          }
        ]
      ]

注意:更改此设置并保存不会更新应用程序中的策略。您需要停止并再次运行“npm start”才能应用这些更改。


6
投票

在违规消息中,您有一个白名单:拒绝连接到...以下内容安全策略指令:“default-src'self''unsafe-inline'数据:”

但在元标记中,您显示了不同的白名单:default-src 'self' 'unsafe-eval'

这意味着您至少有 2 个正在运行的 CSP。多个 CSP 充当一致的过滤器 - 所有打算允许的源都应通过所有过滤器。因此,所有 CSP 都适用最严格的规则。

找出您在哪里发布第一个 CSP 并将

connect-src https://api.myapp.com
添加到其中。并删除meta标签中的CSP。

很可能是某个包通过 HTTP 标头发布了他的默认 CSP(如何检查),因此 Helmet 受到怀疑 - 它从 v4 开始发布默认 CSP。
当然,您可以直接使用以下代码发布 CSP HTTP header:

session.defaultSession.webRequest.onHeadersReceived((details, callback) => {
  callback({ responseHeaders: Object.assign({
    ...details.responseHeaders,
    "Content-Security-Policy": [ "default-src 'self' 'unsafe-inline' data:" ]
    }, details.responseHeaders)});
  });

5
投票

如果您使用 forge.config.ts,您可以使用:

plugins: [
    new WebpackPlugin({
      mainConfig,
      devContentSecurityPolicy: "connect-src 'self' * 'unsafe-eval'",
      renderer: {
        config: rendererConfig,
        entryPoints: [
          {
            html: './src/index.html',
            js: './src/index.tsx',
            name: 'main_window',
            preload: {
              js: './src/preload.ts',
            },
          },
        ],
      },
    }),
  ],
};

2
投票

在我的例子中,HTML Meta 是

<meta http-equiv="Content-Security-Policy" 
      content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe inline'" />

我在控制台中遇到的错误

Refused to connect to 'http://127.0.0.1:8000/api/v1/categories' because it violates the following Content Security Policy directive: "default-src 'self'". Note that 'connect-src' was not explicitly set, so 'default-src' is used as a fallback.

因此,正如错误一样,它明确提到了

"default-src 'self'"
。这意味着默认情况下一切的来源都是 self。还提到我需要设置
"connect-src"

我的解决方案,只需将其附加到您的 Content-Security-Policy 元标记中即可

"connect-src http://localhost:* ws://localhost:*"
您可以设置您需要的任何 url 甚至多个 url。喜欢:
connect-src http://127.0.0.1:* ws://localhost:* https://myapiurl.dev

这里

ws://localhost:*
是您的代码 HMR 所必需的,您也可以将 * 替换为您的开发服务器端口。

<meta http-equiv="Content-Security-Policy" 
      content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe inline'; connect-src http://localhost:* ws://localhost:* " />

1
投票

只需从您的

html
代码片段中删除以下行:

<meta http-equiv="Content-Security-Policy" content="default-src 'self' 'unsafe-eval' ">

0
投票

如果您使用helm()函数来提高node js应用程序的安全性,那么只需添加这行代码app.use( app.use(helmet.contentSecurityPolicy({ 指令:{ defaultSrc: ["'self'"], scriptSrc: ["'self'", 'https://unpkg.com'], connectSrc: ["'self'" , 'https://reqres.in'] } }));

© www.soinside.com 2019 - 2024. All rights reserved.