23

I am trying to inject a input HTML tag with Angular 2, here is my project :

    <div [innerHTML]="inputpdf"></div>

The .ts :

export class FaxSendComponent  {
     inputpdf = '<input type="text" name="fname">';
     }

Here is the log from the console :

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

I try with other html tag like <h3> and it works perfectly.

3
  • Why don't you check the link in the warning message? Commented Jul 11, 2016 at 9:27
  • I check it, and i try but it didnt works Commented Jul 11, 2016 at 9:28
  • I just wanted to say that backticks do not work as a solution for this issue. I'm too new to comment underneath the suggestion. Backticks are good practice though. Commented Aug 7, 2017 at 15:55

3 Answers 3

39

You should trust the HTML first before injecting it. You have to use the DomSanitizer for such a thing. An <h3> element is considered safe. An <input> element is not.

Change your FaxSendComponent to something like this:

export class FaxSendComponent  {

    private _inputpdf: string = '<input type="text" name="fname">';

    public get inputpdf() : SafeHtml {
       return this._sanitizer.bypassSecurityTrustHtml(this._inputpdf);
    }

    constructor(private _sanitizer: DomSanitizer){}
}

And have your template stay the same as this:

<div [innerHTML]="inputpdf"></div>

A little heads-up though:

WARNING: calling this method with untrusted user data exposes your application to XSS security risks!

If you plan on using this technique more, you can try to write a Pipe to fulfil this task.

@Pipe({
    name: 'sanitizeHtml'
})
export class SanitizeHtml implements PipeTransform  {

   constructor(private _sanitizer: DomSanitizer){}  

   transform(v: string) : SafeHtml {
      return this._sanitizer.bypassSecurityTrustHtml(v); 
   } 
} 

If you have a pipe like this, your FaxSendComponent will change to this:

@Component({
   selector: 'fax-send',
   template: `<div [innerHTML]="inputpdf | sanitizeHtml"></div>`
})
export class FaxSendComponent  {

    public inputpdf: string = '<input type="text" name="fname">';

}
Sign up to request clarification or add additional context in comments.

5 Comments

I think this is the solution, but i've got an error, Type 'SafeHtml' is not assignable to type 'string'.
@AlexyVercruysse Yes, I've updated my answer. That was just a TypeScript error. bypassSecurityTrustHtml returns SafeHtml, and not a string. So I had to change the return value on the getter
Here are the imports: import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
how do i append this using document.getElementsByTagName('head')[0].appendChild(script). Since i cannot sanitize the script variable which is a string
lifesaver. awesome solution!
8

create sanitizing.ts file when you use it for bind inner html.

import { Pipe, PipeTransform } from "@angular/core";
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';

@Pipe({
  name: 'sanitizeHtml'
})
export class SanitizeHtmlPipe implements PipeTransform {

  constructor(private _sanitizer:DomSanitizer) {
  }

  transform(v:string):SafeHtml {
    return this._sanitizer.bypassSecurityTrustHtml(v);
  }
}

now register this module into your app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { routes } from './app.routing';

import { SanitizeHtmlPipe } from './product_details/filter';

@NgModule({
  declarations: [
    SanitizeHtmlPipe
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule,
    BrowserAnimationsModule,
    CookieLawModule,
    routes
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

now use when you can bind your html eg. productDetails.html

<section class="multiple-img">
   <div class="container" *ngIf="product_details">
    <div class="row">
      <h1 class="main-titel-text">Detail</h1>
    </div>
    <div class="row">
      <div class="col-md-3 col-sm-3 col-xs-12">
        <div class="product-box-div">
          <div class="product-img-div">
            <img src="{{image_url.product_images}}{{product_details.product_image}}" alt="Product"/>
          </div>
          <div class="product-name-div">Name:- {{ product_details.product_name }}</div>
          <div class="product-name-div">Price:- {{ product_details.product_price }}</div>
          <div class="product-name-div">Selling Price:- {{ product_details.product_discount_price }}</div>
          <div class="product-name-div" [innerHTML]="product_details.product_description | sanitizeHtml"></div>
        </div>
      </div>
    </div>
  </div>
</section>

1 Comment

To write a test case for sanitizing.ts, how to import or use DomSanitizier?
0

Try using backticks - ` - instead of the single quotes - ' -

2 Comments

backticks are used for template strings (so outputting HTML from your JS/TS). It's not always needed, but I think it's a good practice to always use backticks.
Backticks do not do anything relating to scrubbing HTML, they simply give you templating abilities and multi-line strings. basarat.gitbooks.io/typescript/content/docs/…

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.