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/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.