Inserting HTML via Angular 2: Use of DomSanitizationService & bypassSecurityTrustHtml

Does anyone have any experience inserting HTML into your Ionic 2 application and bypassing Angular 2’s Cross-site Scripting Security Model by using the DomSanitizationService? I am trying to do so, but it does not appear to be working as my HTML is still being sanitized. My console reads:

WARNING: sanitizing HTML stripped some content (see http://g.co/ng/security#xss).

I was wondering if anyone has successfully managed to get this to work? My approach is based on the solution mentioned in this stackoverflow post.

I import the DomSanitizationService as follows:

import {DomSanitizationService} from '@angular/platform-browser/esm/src/security/dom_sanitization_service';

I add it to my constructor:

constructor(private _sanitizer: DomSanitizationService) {  }

I then construct my function as follows:

assembleHTMLItem() {
  var strHTML = '<input type="text" name="name">';
  return this._sanitizer.bypassSecurityTrustHtml(strHTML);
}

And call it during the ionViewLoaded function

this.htmlValue = this.assembleHTMLItem();

My HTML looks like this:

<div [innerHTML]="htmlValue">

As mentioned, this isn’t working for me as Angular 2 is still sanitizing the htmlValue value. Has anyone successfully managed to get this to work?

EDIT: I’m also getting the following error in my CLI, so perhaps I’m not importing DomSanitizationService correctly?

C:\<<project location>>\node_modules\@angular\platform-browser\esm\src\security\dom_sanitization_service.js:8
import { Injectable } from '@angular/core';
^
ParseError: 'import' and 'export' may appear only with 'sourceType: module'

I recently created a pipe to make it simpler to mark values as trusted/safe.

You can use it to bypass html sanitization like this in templates:

<div [innerHTML]="product.description | safe: 'html'"></div>

Or if you need to bypass style sanitization:

<div [style.background-image]="'url(' + product.imageUrl + ')' | safe: 'style'"></div>

‘script’, ‘url’ and ‘resourceUrl’ is also supported. Read more here: https://angular.io/docs/ts/latest/api/platform-browser/index/DomSanitizationService-class.html

Here’s the SafePipe code:

import {Pipe} from '@angular/core';
import {DomSanitizationService, SafeHtml, SafeStyle, SafeScript, SafeUrl, SafeResourceUrl} from '@angular/platform-browser';

@Pipe({
	name: 'safe'
})
export class SafePipe {

	constructor(protected _sanitizer: DomSanitizationService) {

	}

	public transform(value: string, type: string): SafeHtml | SafeStyle | SafeScript | SafeUrl | SafeResourceUrl {
		switch (type) {
			case 'html':
				return this._sanitizer.bypassSecurityTrustHtml(value);
			case 'style':
				return this._sanitizer.bypassSecurityTrustStyle(value);
			case 'script':
				return this._sanitizer.bypassSecurityTrustScript(value);
			case 'url':
				return this._sanitizer.bypassSecurityTrustUrl(value);
			case 'resourceUrl':
				return this._sanitizer.bypassSecurityTrustResourceUrl(value);
			default:
				throw new Error(`Unable to bypass security for invalid type: ${type}`);
		}
	}

}

14 Likes

Where I put the code ?

*sorry, I’m newbie on Ionic 2 :smiley:

1 Like

Just a note that DomSanitizationService has been renamed to DomSanitizer.

6 Likes

Updated to use DomSanitizer (DomSanitizationService was renamed to DomSanitizer in Angular RC 6):

import { Pipe } from '@angular/core';
import { DomSanitizer, SafeHtml, SafeStyle, SafeScript, SafeUrl, SafeResourceUrl } from '@angular/platform-browser';

@Pipe({
	name: 'safe'
})
export class SafePipe {

	constructor(protected _sanitizer: DomSanitizer) {

	}

	public transform(value: string, type: string = 'html'): SafeHtml | SafeStyle | SafeScript | SafeUrl | SafeResourceUrl {
		switch (type) {
			case 'html': return this._sanitizer.bypassSecurityTrustHtml(value);
			case 'style': return this._sanitizer.bypassSecurityTrustStyle(value);
			case 'script': return this._sanitizer.bypassSecurityTrustScript(value);
			case 'url': return this._sanitizer.bypassSecurityTrustUrl(value);
			case 'resourceUrl': return this._sanitizer.bypassSecurityTrustResourceUrl(value);
			default: throw new Error(`Invalid safe type specified: ${type}`);
		}
	}

}
6 Likes

I’ve been using your SafePipe for a couple of months - and it’s awesome. Just upgraded to latest Ionic framework and this no longer works - and I’m trying to figure out where it’s failing. I don’t think it’s your pipe as I’ve coded the same directly inside of my code. Do you know if the technique for embedding HTML into an Ionic page has changed?

I’m using it like this, as expected:

<div [innerHTML]="calendar_html | safe: 'html'"></div>

My environment:

Cordova CLI: 6.4.0 
Ionic Framework Version: 2.2.0
Ionic CLI Version: 2.2.1
Ionic App Lib Version: 2.2.0
Ionic App Scripts Version: 1.1.4
ios-deploy version: 1.9.0 
ios-sim version: 5.0.11 
OS: macOS Sierra
Node Version: v6.9.3
Xcode version: Xcode 8.2.1 Build version 8C1002

I discovered that the pipe is working just fine but that injecting ion-grid stuff into a page produces strange results now. Could be related to how the injected code discovered the size of the parent window. I changed my tabled-oriented code to just use divs instead of an ion-grid.

HI,thanks your answer,But I use your code to this, i have a error

The pipe 'safe' could not be found

I have fixed it,Sorry by my disturb :grinning:

This works sometimes but i get the following undefined on some of my content

none of them working, i found a solution for myself after searching tons of docs on google.

here it is a working one.

on your .ts
import { DomSanitizer } from ‘@angular/platform-browser’;

in your export class

public qna_private_url;
constructor(public sanitizer: DomSanitizer, … )
{
this.qna_private_url = this.sanitizer.bypassSecurityTrustResourceUrl(‘http://www.someting.com/something/’);
}

and finally your html

hi please what do you mean by this row
I don’t understande it
: SafeHtml | SafeStyle | SafeScript | SafeUrl | SafeResourceUrl

thanks in advanced

I am also facing the same error

how do you solved that ?

Import SafePipe and add to your module.

I solved that by importing

import {DomSanitizer} from '@angular/platform-browser'

constructor(private sanitizer: DomSanitizer)

this.html = sanitizer.bypassSecurityTrustHtml('html code with css styling');

and in HTML

<p [innerHTML]="html"></p>

4 Likes

Man… I just signed in to thank you from the bottom of my heart!!! You just saved the day here!!! Really!!! Cheers!

1 Like