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);
Angular CSP is a security feature that makes your site less vulnerable to attacks like XSS. You can use this feature to specify whether your site should allow in-line JavaScript or not. In addition, you can specify policies for other content like AJAX, CSS, and iframe.
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.
Using ahead-of-time compilation solves the problem. The following command can be used to build an application working with restrictive CSP.
ng build --prod
To test it locally you can use
ng serve --prod
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With