From e8d47c2d41ede1bf2f0392a0196f09e1858e2276 Mon Sep 17 00:00:00 2001 From: Bjarki Date: Sat, 10 Oct 2020 01:13:32 +0000 Subject: [PATCH] feat(core): allow returning Trusted Types from SanitizerFn (#39218) Sanitizers in Angular currently return strings, which will then eventually make their way down to the DOM, e.g. as the value of an attribute or property. This may cause a Trusted Types violation. As a step towards fixing that, make it possible to return Trusted Types from the SanitizerFn interface, which represents the internal sanitization pipeline. DOM renderer interfaces are also updated to reflect the fact that setAttribute and setAttributeNS must be able to accept Trusted Types. PR Close #39218 --- packages/core/src/render3/interfaces/renderer.ts | 11 ++++++++--- packages/core/src/render3/interfaces/sanitization.ts | 5 ++++- packages/core/src/sanitization/sanitization.ts | 6 +++--- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/packages/core/src/render3/interfaces/renderer.ts b/packages/core/src/render3/interfaces/renderer.ts index f2cd45492e..7f3b640090 100644 --- a/packages/core/src/render3/interfaces/renderer.ts +++ b/packages/core/src/render3/interfaces/renderer.ts @@ -16,6 +16,7 @@ */ import {RendererStyleFlags2, RendererType2} from '../../render/api'; +import {TrustedHTML, TrustedScript, TrustedScriptURL} from '../../util/security/trusted_type_defs'; import {getDocument} from './document'; // TODO: cleanup once the code is merged in angular/angular @@ -80,7 +81,9 @@ export interface ProceduralRenderer3 { parentNode(node: RNode): RElement|null; nextSibling(node: RNode): RNode|null; - setAttribute(el: RElement, name: string, value: string, namespace?: string|null): void; + setAttribute( + el: RElement, name: string, value: string|TrustedHTML|TrustedScript|TrustedScriptURL, + namespace?: string|null): void; removeAttribute(el: RElement, name: string, namespace?: string|null): void; addClass(el: RElement, name: string): void; removeClass(el: RElement, name: string): void; @@ -157,9 +160,11 @@ export interface RElement extends RNode { classList: RDomTokenList; className: string; textContent: string|null; - setAttribute(name: string, value: string): void; + setAttribute(name: string, value: string|TrustedHTML|TrustedScript|TrustedScriptURL): void; removeAttribute(name: string): void; - setAttributeNS(namespaceURI: string, qualifiedName: string, value: string): void; + setAttributeNS( + namespaceURI: string, qualifiedName: string, + value: string|TrustedHTML|TrustedScript|TrustedScriptURL): void; addEventListener(type: string, listener: EventListener, useCapture?: boolean): void; removeEventListener(type: string, listener?: EventListener, options?: boolean): void; diff --git a/packages/core/src/render3/interfaces/sanitization.ts b/packages/core/src/render3/interfaces/sanitization.ts index 886ff809c9..3ebbb7c35a 100644 --- a/packages/core/src/render3/interfaces/sanitization.ts +++ b/packages/core/src/render3/interfaces/sanitization.ts @@ -6,7 +6,10 @@ * found in the LICENSE file at https://angular.io/license */ +import {TrustedHTML, TrustedScript, TrustedScriptURL} from '../../util/security/trusted_type_defs'; + /** * Function used to sanitize the value before writing it into the renderer. */ -export type SanitizerFn = (value: any, tagName?: string, propName?: string) => string; +export type SanitizerFn = (value: any, tagName?: string, propName?: string) => + string|TrustedHTML|TrustedScript|TrustedScriptURL; diff --git a/packages/core/src/sanitization/sanitization.ts b/packages/core/src/sanitization/sanitization.ts index 49b151a1e0..2be379e468 100644 --- a/packages/core/src/sanitization/sanitization.ts +++ b/packages/core/src/sanitization/sanitization.ts @@ -36,7 +36,7 @@ import {_sanitizeUrl as _sanitizeUrl} from './url_sanitizer'; * * @codeGenApi */ -export function ɵɵsanitizeHtml(unsafeHtml: any): string { +export function ɵɵsanitizeHtml(unsafeHtml: any): TrustedHTML|string { const sanitizer = getSanitizer(); if (sanitizer) { return sanitizer.sanitize(SecurityContext.HTML, unsafeHtml) || ''; @@ -107,7 +107,7 @@ export function ɵɵsanitizeUrl(unsafeUrl: any): string { * * @codeGenApi */ -export function ɵɵsanitizeResourceUrl(unsafeResourceUrl: any): string { +export function ɵɵsanitizeResourceUrl(unsafeResourceUrl: any): TrustedScriptURL|string { const sanitizer = getSanitizer(); if (sanitizer) { return sanitizer.sanitize(SecurityContext.RESOURCE_URL, unsafeResourceUrl) || ''; @@ -130,7 +130,7 @@ export function ɵɵsanitizeResourceUrl(unsafeResourceUrl: any): string { * * @codeGenApi */ -export function ɵɵsanitizeScript(unsafeScript: any): string { +export function ɵɵsanitizeScript(unsafeScript: any): TrustedScript|string { const sanitizer = getSanitizer(); if (sanitizer) { return sanitizer.sanitize(SecurityContext.SCRIPT, unsafeScript) || '';