web-dev-qa-db-fra.com

Make Angular working with restrictive Content Security Policy (CSP)

Je ne peux pas faire fonctionner l'application Angular2 (finale) de base avec le CSP restrictif suivant.

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

Il y a une erreur unsafe-eval dans lang.js et deux dans zone.js . Pourriez-vous fournir une solution?

Étape pour reproduire avec Angular CLI

J'ai créé un référentiel GitHub . Vous pouvez également suivre les instructions ci-dessous.

Utilisez la dernière Angular CLI avec webpack 6.0.8 et la nouvelle application créée avec les instructions ci-dessous.

ng new csp-test

Insérez dans le fichier index.html la balise Meta définissant la politique de sécurité de contenu restrictive suivante.

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

Ensuite, servez l'application.

ng serve

Accès http: // localhost: 4200 / , la page ne se charge pas car les scripts sont bloqués par CSP.

Les erreurs

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'".

avec le code source.

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'".(…)

avec le code source.

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

Le problème a été résolu en utilisant la dernière Angular CLI (à partir de 1.0.0-beta.17). La commande suivante sert une application qui fonctionne car elle inclut une compilation en temps réel.

ng serve --prod
6
Nicolas Henneaux

Réponse modifiée pour @ angular/cli> = 8.2

Depuis ce fil Github , on peut utiliser la propriété index dans angular.json pour contrôler la génération de l'index HTML de l'application:

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

Réponse originale

J'ai trouvé un moyen d'avoir un CSP restrictif sur mon environnement de production tout en étant capable d'utiliser le compilateur JTI pour le développement.

  • Ajoutez un deuxième fichier: index.production.html dans le dossier src.
  • Copiez le contenu de index.html à ce fichier et ajoutez l'en-tête CSP restrictif.
<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'">
  • Ajoutez ensuite à votre angular.json le suivant:
build: {
  ...
  "configurations": {
    "production": {
      "fileReplacements": [
        {
          "replace": "src/index.html",
          "with": "src/index.production.html"
        }
      ],
      ...
    }
  }
}

Cela garantit que lorsque vous exécutez une génération de production, il utilise le index.production.html avec le CSP restrictif, et lorsque vous l'exécutez localement, vous pouvez utiliser le compilateur JTI.

5
Jesse

L'utilisation du compilateur de modèles hors ligne devrait résoudre ce problème.

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

3
Günter Zöchbauer