fix(core): use Trusted Types policy in inert DOM builder (#39208)
When Angular is used in an environment that enforces Trusted Types, the inert DOM builder raises a Trusted Types violation due to its use of DOMParser and element.innerHTML with plain strings. Since it is only used internally (in the HTML sanitizer and for i18n ICU parsing), we update it to use Angular's Trusted Types policy to promote the provided HTML to TrustedHTML. PR Close #39208
This commit is contained in:
parent
b642f0bf45
commit
7d4929918d
|
@ -6,6 +6,8 @@
|
||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import {trustedHTMLFromString} from '../util/security/trusted_types';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This helper is used to get hold of an inert tree of DOM elements containing dirty HTML
|
* This helper is used to get hold of an inert tree of DOM elements containing dirty HTML
|
||||||
* that needs sanitizing.
|
* that needs sanitizing.
|
||||||
|
@ -36,8 +38,9 @@ class DOMParserHelper implements InertBodyHelper {
|
||||||
// in `html` from consuming the otherwise explicit `</body>` tag.
|
// in `html` from consuming the otherwise explicit `</body>` tag.
|
||||||
html = '<body><remove></remove>' + html;
|
html = '<body><remove></remove>' + html;
|
||||||
try {
|
try {
|
||||||
const body = new (window as any).DOMParser().parseFromString(html, 'text/html').body as
|
const body = new window.DOMParser()
|
||||||
HTMLBodyElement;
|
.parseFromString(trustedHTMLFromString(html) as string, 'text/html')
|
||||||
|
.body as HTMLBodyElement;
|
||||||
body.removeChild(body.firstChild!);
|
body.removeChild(body.firstChild!);
|
||||||
return body;
|
return body;
|
||||||
} catch {
|
} catch {
|
||||||
|
@ -71,7 +74,7 @@ class InertDocumentHelper implements InertBodyHelper {
|
||||||
// Prefer using <template> element if supported.
|
// Prefer using <template> element if supported.
|
||||||
const templateEl = this.inertDocument.createElement('template');
|
const templateEl = this.inertDocument.createElement('template');
|
||||||
if ('content' in templateEl) {
|
if ('content' in templateEl) {
|
||||||
templateEl.innerHTML = html;
|
templateEl.innerHTML = trustedHTMLFromString(html) as string;
|
||||||
return templateEl;
|
return templateEl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,7 +86,7 @@ class InertDocumentHelper implements InertBodyHelper {
|
||||||
// down the line. This has been worked around by creating a new inert `body` and using it as
|
// down the line. This has been worked around by creating a new inert `body` and using it as
|
||||||
// the root node in which we insert the HTML.
|
// the root node in which we insert the HTML.
|
||||||
const inertBody = this.inertDocument.createElement('body');
|
const inertBody = this.inertDocument.createElement('body');
|
||||||
inertBody.innerHTML = html;
|
inertBody.innerHTML = trustedHTMLFromString(html) as string;
|
||||||
|
|
||||||
// Support: IE 9-11 only
|
// Support: IE 9-11 only
|
||||||
// strip custom-namespaced attributes on IE<=11
|
// strip custom-namespaced attributes on IE<=11
|
||||||
|
@ -129,7 +132,8 @@ class InertDocumentHelper implements InertBodyHelper {
|
||||||
*/
|
*/
|
||||||
export function isDOMParserAvailable() {
|
export function isDOMParserAvailable() {
|
||||||
try {
|
try {
|
||||||
return !!new (window as any).DOMParser().parseFromString('', 'text/html');
|
return !!new window.DOMParser().parseFromString(
|
||||||
|
trustedHTMLFromString('') as string, 'text/html');
|
||||||
} catch {
|
} catch {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue