I cannot make base Angular2 (final) application works with the following restrictive CSP.
default-src 'none';
script-src 'self';
style-src 'self';
font-src 'self';
img-src 'self' data:;
connect-src 'self'
There are one unsafe-eval error in lang.js and two in zone.js. Could you provide a solution ?
I have created a GitHub repository. You can also follow the instructions below.
Use the last Angular CLI with Webpack 6.0.8 and the new application created with the instructions below.
ng new csp-test
Insert in the index.html
the meta tag defining the following restrictive Content Security Policy.
<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'">
Then serve the application.
ng serve
Access http://localhost:4200/, the page does not load since scripts are blocked by CSP.
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'".
with the source code.
335: return new (Function.bind.apply(Function, [void 0].concat(fnArgNames.concat(fnBody))))().apply(void 0, fnArgValues);
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'".(…)
with the source code.
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);
Edited answer for @angular/cli>=8.2
From this Github thread, one can use the index
property in angular.json
to control the generation of the application's HTML index:
build: {
...
"configurations": {
"production": {
"index": {
"input": "src/index.production.html",
"output": "index.html"
},
...
}
}
}
Original answer
I've found a way to have restrictive CSP on my production environment while still being able to use the JTI compliler for development.
index.production.html
to the src
folder.index.html
to that file, and add the restrictive CSP header.<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
the following:build: {
...
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "src/index.html",
"with": "src/index.production.html"
}
],
...
}
}
}
This makes sure that when you run a production build, it will use the index.production.html
with the restrictive CSP, and when you're running it locally, you can use the JTI compiler.