(defaultDoc: any, unsafeHtmlInput: string)
| 302 | * the DOM in a browser environment. |
| 303 | */ |
| 304 | export function _sanitizeHtml(defaultDoc: any, unsafeHtmlInput: string): TrustedHTML | string { |
| 305 | let inertBodyElement: HTMLElement | null = null; |
| 306 | try { |
| 307 | inertBodyHelper = inertBodyHelper || getInertBodyHelper(defaultDoc); |
| 308 | // Make sure unsafeHtml is actually a string (TypeScript types are not enforced at runtime). |
| 309 | let unsafeHtml = unsafeHtmlInput ? String(unsafeHtmlInput) : ''; |
| 310 | inertBodyElement = inertBodyHelper.getInertBodyElement(unsafeHtml); |
| 311 | |
| 312 | // mXSS protection. Repeatedly parse the document to make sure it stabilizes, so that a browser |
| 313 | // trying to auto-correct incorrect HTML cannot cause formerly inert HTML to become dangerous. |
| 314 | let mXSSAttempts = 5; |
| 315 | let parsedHtml = unsafeHtml; |
| 316 | |
| 317 | do { |
| 318 | if (mXSSAttempts === 0) { |
| 319 | throw new Error('Failed to sanitize html because the input is unstable'); |
| 320 | } |
| 321 | mXSSAttempts--; |
| 322 | |
| 323 | unsafeHtml = parsedHtml; |
| 324 | parsedHtml = inertBodyElement!.innerHTML; |
| 325 | inertBodyElement = inertBodyHelper.getInertBodyElement(unsafeHtml); |
| 326 | } while (unsafeHtml !== parsedHtml); |
| 327 | |
| 328 | const sanitizer = new SanitizingHtmlSerializer(); |
| 329 | const safeHtml = sanitizer.sanitizeChildren( |
| 330 | (getTemplateContent(inertBodyElement!) as Element) || inertBodyElement, |
| 331 | ); |
| 332 | if ((typeof ngDevMode === 'undefined' || ngDevMode) && sanitizer.sanitizedSomething) { |
| 333 | console.warn(`WARNING: sanitizing HTML stripped some content, see ${XSS_SECURITY_URL}`); |
| 334 | } |
| 335 | |
| 336 | return trustedHTMLFromString(safeHtml); |
| 337 | } finally { |
| 338 | // In case anything goes wrong, clear out inertElement to reset the entire DOM structure. |
| 339 | if (inertBodyElement) { |
| 340 | const parent = getTemplateContent(inertBodyElement) || inertBodyElement; |
| 341 | while (parent.firstChild) { |
| 342 | parent.firstChild.remove(); |
| 343 | } |
| 344 | } |
| 345 | } |
| 346 | } |
| 347 | |
| 348 | export function getTemplateContent(el: Node): Node | null { |
| 349 | return 'content' in (el as any) /** Microsoft/TypeScript#21517 */ && isTemplateElement(el) |
no test coverage detected
searching dependent graphs…