'Angular: how to set up Content-Security-Policy & Trusted Types?
Having read the Angular security guidelines, I would like to:
- configure the content security policy
- enable the trusted types enforcement
Here is how I changed my index.html so far:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; style-src 'self' 'unsafe-inline';" />
<meta http-equiv="Content-Security-Policy" content="trusted-types angular angular#unsafe-bypass; require-trusted-types-for 'script';" />
Right now, I have got a lot of errors in my console:
This document requires 'TrustedScript' assignment.
FooService EvalError: Refused to evaluate a string as JavaScript because this document requires 'Trusted Type' assignment.
My questions:
- Is it OK to define the
Content-Security-Policy
twice/for the both:
One for the "classic" CSP configuration, one for the trusted types?
Does it make sense? - How do they relate with each other?
- How do I make it work both locally and in production?
- I understood that this configuration should probably be activated only in production environments (because of JIT),
using a specific index.production.html file (see).
I am not a big fan of duplicating the index.html just for two meta properties... - I also saw that I could use the
headers
property in myarchitect.serve.configurations.production
,
but I am not sure if it is better and/or equivalent
- I understood that this configuration should probably be activated only in production environments (because of JIT),
- Should I even use the
trusted-types
?
It is recommended by the Angular security guidelines, but still experimental
I read some interesting resources, but they do not show how to concretely use the CSP attribute.
I am using Angular 13.
Solution 1:[1]
You can have multiple CSPs. All of them will be checked separately and your content need to pass all policies. You can have one intended for CSP level 2 and one for CSP level 3 (where level 2 browsers will ignore directives it doesn't understand).
I would recommend setting CSP as a response header. It is simpler to configure per environment and more features are available such as report-uri and frame-ancestors.
Trusted types adds another layer of security and I would implement it if possible after mastering the basic CSP.
Solution 2:[2]
Just add "safevalues": "^0.1.8" to dependencies and "@types/trusted-types": "^2.0.2" to devDependencies and use it in your code like this:
import {unwrapHtmlForSink} from 'safevalues';
import {createHtml} from 'safevalues/implementation/html_impl';
...
this.r.setProperty(this.inputValue.nativeElement, 'innerHTML', unwrapHtmlForSink(createHtml('some_html')));
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Halvor Sakshaug |
Solution 2 |