web-dev-qa-db-ja.com

Angular制限的なコンテンツセキュリティポリシー(CSP)を使用する]を作成する

ベースのAngular2(最終)アプリケーションを次の制限付きCSPで動作させることはできません。

default-src 'none';
script-src 'self';
style-src 'self';
font-src 'self';
img-src 'self' data:;
connect-src 'self'

lang.js に1つunsafe-evalエラーがあり、 zone.js に2つエラーがあります。解決策を提供できますか?

Angular CLIで再現する手順

GitHubリポジトリ を作成しました。以下の手順に従うこともできます。

最後のAngular CLIとwebpack 6.0.8、および以下の手順で作成された新しいアプリケーションを使用します。

ng new csp-test

次の制限的なコンテンツセキュリティポリシーを定義するメタタグをindex.htmlに挿入します。

<meta 
  http-equiv="Content-Security-Policy" 
  content="default-src 'none';script-src 'self';style-src 'self';font-src 'self';img-src 'self' data:;connect-src 'self'">

次に、アプリケーションを提供します。

ng serve

アクセス http:// localhost:4200 / 、スクリプトはCSPによってブロックされているため、ページはロードされません。

エラー

Error in Chrome

lang.js

lang.js:335 Uncaught EvalError: Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src 'self'".

ソースコード付き。

335: return new (Function.bind.apply(Function, [void 0].concat(fnArgNames.concat(fnBody))))().apply(void 0, fnArgValues);

zone.js

zone.js:344 Unhandled Promise rejection: Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src 'self'".
 ; Zone: <root> ; Task: Promise.then ; Value: EvalError: Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src 'self'".

zone.js:346 Error: Uncaught (in promise): EvalError: Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src 'self'".(…)

ソースコード付き。

343: if (rejection) {
344:     console.error('Unhandled Promise rejection:', rejection instanceof Error ? rejection.message : rejection, '; Zone:', e.zone.name, '; Task:', e.task && e.task.source, '; Value:', rejection, rejection instanceof Error ? rejection.stack : undefined);
345: }
346: console.error(e);
34

この問題は、最新のAngular CLIバージョン(1.0.0-beta.17以降)を使用して解決されました。)次のコマンドには、事前コンパイルが含まれているため、動作するアプリケーションに役立ちます。

ng serve --prod
6

@ angular/cli> = 8.2の編集された回答

このGithubスレッド から、angular.jsonindexプロパティを使用して、アプリケーションのHTMLインデックスの生成を制御できます。

build: {
  ...
  "configurations": {
    "production": {
      "index": {
        "input": "src/index.production.html",
         "output": "index.html"
       },
      ...
    }
  }
}

元の答え

JTIコンパイラーを開発に使用しながら、実稼働環境で制限付きのCSPを使用する方法を見つけました。

  • 2番目のファイルindex.production.htmlsrcフォルダーに追加します。
  • index.htmlの内容をそのファイルにコピーし、制限付きのCSPヘッダーを追加します。
<meta http-equiv="Content-Security-Policy" 
content="default-src 'none';
  frame-src 'self';
  script-src 'self';
  style-src 'self' 'unsafe-inline';
  font-src 'self';
  img-src 'self' data:;
  connect-src 'self'">
  • 次に、angular.jsonに以下を追加します。
build: {
  ...
  "configurations": {
    "production": {
      "fileReplacements": [
        {
          "replace": "src/index.html",
          "with": "src/index.production.html"
        }
      ],
      ...
    }
  }
}

これにより、プロダクションビルドを実行すると、制限付きのCSPでindex.production.htmlが使用され、ローカルで実行している場合はJTIコンパイラーを使用できるようになります。

5
Jesse

オフラインテンプレートコンパイラを使用すると、これを修正できます。

http://www.syntaxsuccess.com/viewarticle/offline-compilation-in-angular-2.https://github.com/angular/angular/issues/1744

3