如何使用 Angular [innerHTML] 修复 TrustedHTML 分配错误
How to fix TrustedHTML assignment error with Angular [innerHTML]
(看来我的问题与getting error `This document requires 'TrustedHTML' assignment` in chrome有关,但我使用的是Angular v10)
描述:
当我在 Angular 10(或以下)项目上使用 [innerHTML]="myVar"
指令时,使用严格的 CSP require-trusted-types-for 'script';
它失败并显示消息:
This document requires 'TrustedHTML' assignment. ERROR TypeError:
Failed to set the 'innerHTML' property on 'Element': This document
requires 'TrustedHTML' assignment.
重现方式:
- 打开一个 Angular X 项目
- 在模板中使用
[innerHTML]="someVar"
指令
- 添加一个
require-trusted-types-for 'script';
CSP header
- 检查 Chrome 控制台 ;)
我试过的:
在阅读了一些关于可信类型的资料后,例如:
- https://web.dev/trusted-types/
- https://www.intricatecloud.io/2019/10/using-angular-innerhtml-to-display-user-generated-content-without-sacrificing-security/
我尝试在我的 Angular 项目中使用 https://github.com/cure53/DOMPurify。只需添加包,创建一个 Angular 管道,然后在模板中使用它。
可以使用以下代码创建管道:
import { Pipe, PipeTransform } from '@angular/core';
import * as DOMPurify from 'dompurify';
@Pipe({
name: 'safeHtml'
})
export class SafeHtmlPipe implements PipeTransform {
transform(value: string): TrustedHTML {
return DOMPurify.sanitize(value, {RETURN_TRUSTED_TYPE: true});
}
}
并且可以这样使用:[innerHTML]="myVar | safeHtml"
当然,我用 console.log
检查了 return,它给了我一个真正的 TrustedHTML object。
Chrome 控制台中弹出新错误,因此我必须添加一个新的 CSP header 来授权 DOMPurify:
require-trusted-types-for 'script';trusted-types dompurify
之后,Chrome 很高兴看到 DOMPurify 字符串操作。
但是,初始错误re-emerges!
我不明白我错过了什么 - Chrome 对 innerHTML 调用中的 TrustedHTML 类型的抱怨,所以我进行了 TrustedHTML 转换。之后 Chrome 想要 dompurify 的明确授权,所以我这样做了,然后 Chrome 再次抱怨 TrustedHTML 类型...
避免错误的方法:
添加 CSP require-trusted-types-for 'script';trusted-types default
(来源 https://w3c.github.io/webappsec-trusted-types/dist/spec/#default-policy-hdr)
添加一个特定于 innerHTML 方法的小片段:
if (window.trustedTypes && window.trustedTypes.createPolicy) {
window.trustedTypes.createPolicy('default', {
createHTML: (string, sink) => string
});
}
这里有一些提示:https://github.com/angular/angular/pull/32353
请谨慎使用此方法,因为它会将对 innerHTML 的每个分配都标记为受信任,但并不能确保它实际上是安全的。本质上,它回避了受信任类型的要点,因为这种方法不再阻止注入漏洞(例如,this.div.nativeElement.innerHTML = userInput)。
(看来我的问题与getting error `This document requires 'TrustedHTML' assignment` in chrome有关,但我使用的是Angular v10)
描述:
当我在 Angular 10(或以下)项目上使用 [innerHTML]="myVar"
指令时,使用严格的 CSP require-trusted-types-for 'script';
它失败并显示消息:
This document requires 'TrustedHTML' assignment. ERROR TypeError: Failed to set the 'innerHTML' property on 'Element': This document requires 'TrustedHTML' assignment.
重现方式:
- 打开一个 Angular X 项目
- 在模板中使用
[innerHTML]="someVar"
指令 - 添加一个
require-trusted-types-for 'script';
CSP header - 检查 Chrome 控制台 ;)
我试过的:
在阅读了一些关于可信类型的资料后,例如:
- https://web.dev/trusted-types/
- https://www.intricatecloud.io/2019/10/using-angular-innerhtml-to-display-user-generated-content-without-sacrificing-security/
我尝试在我的 Angular 项目中使用 https://github.com/cure53/DOMPurify。只需添加包,创建一个 Angular 管道,然后在模板中使用它。
可以使用以下代码创建管道:
import { Pipe, PipeTransform } from '@angular/core';
import * as DOMPurify from 'dompurify';
@Pipe({
name: 'safeHtml'
})
export class SafeHtmlPipe implements PipeTransform {
transform(value: string): TrustedHTML {
return DOMPurify.sanitize(value, {RETURN_TRUSTED_TYPE: true});
}
}
并且可以这样使用:[innerHTML]="myVar | safeHtml"
当然,我用 console.log
检查了 return,它给了我一个真正的 TrustedHTML object。
Chrome 控制台中弹出新错误,因此我必须添加一个新的 CSP header 来授权 DOMPurify:
require-trusted-types-for 'script';trusted-types dompurify
之后,Chrome 很高兴看到 DOMPurify 字符串操作。
但是,初始错误re-emerges!
我不明白我错过了什么 - Chrome 对 innerHTML 调用中的 TrustedHTML 类型的抱怨,所以我进行了 TrustedHTML 转换。之后 Chrome 想要 dompurify 的明确授权,所以我这样做了,然后 Chrome 再次抱怨 TrustedHTML 类型...
避免错误的方法:
添加 CSP require-trusted-types-for 'script';trusted-types default
(来源 https://w3c.github.io/webappsec-trusted-types/dist/spec/#default-policy-hdr)
添加一个特定于 innerHTML 方法的小片段:
if (window.trustedTypes && window.trustedTypes.createPolicy) {
window.trustedTypes.createPolicy('default', {
createHTML: (string, sink) => string
});
}
这里有一些提示:https://github.com/angular/angular/pull/32353
请谨慎使用此方法,因为它会将对 innerHTML 的每个分配都标记为受信任,但并不能确保它实际上是安全的。本质上,它回避了受信任类型的要点,因为这种方法不再阻止注入漏洞(例如,this.div.nativeElement.innerHTML = userInput)。