Подтвердить что ты не робот

Заставьте 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 есть одна небезопасная ошибка и две в zone.js. Не могли бы вы предоставить решение?

Шаг для воспроизведения с Angular CLI

Я создал GitHub-репозиторий. Вы также можете следовать приведенным ниже инструкциям.

Используйте последний Angular CLI с веб-пакетом 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);
4b9b3361

Ответ 1

Проблема была решена с использованием последней версии Angular CLI (начиная с 1.0.0-beta.17). Следующая команда служит рабочему приложению, поскольку включает компиляцию с опережением времени.

ng serve --prod

Ответ 3

Я нашел способ использовать ограниченный CSP в своей производственной среде, при этом все еще имея возможность использовать JTI-компилятор для разработки.

  • Добавьте второй файл: index.production.html в папку src.
  • Скопируйте содержимое 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"
        }
      ],
      ...
    }
  }
}

Это гарантирует, что при запуске производственной сборки будет использоваться index.production.html с ограничительным CSP, а когда вы запускаете его локально, вы можете использовать JTI-компилятор.