91

My problem, that when I use innererHtml binding - angular2 remove all styles attributes. It's important for me, bacause in my task - html is generated on server-side with all styles. Example:

@Component({
  selector: 'my-app',
  template: `
    <input type="text" [(ngModel)]="html">
    <div [innerHtml]="html">
    </div>
  `,
})
export class App {
  name:string;
  html: string;
  constructor() {
    this.name = 'Angular2'
    this.html = "<span style=\"color:red;\">1234</span>";
  }
}

But in DOM I see only 1234 and this text is not red.

http://plnkr.co/edit/UQJOFMKl9OwMRIJ38U8D?p=preview

Thank you!

0

3 Answers 3

209

You can leverage DomSanitized to avoid it.

The easiest way is to create custom pipe like:

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

@Pipe({ name: 'safeHtml'})
export class SafeHtmlPipe implements PipeTransform  {
  constructor(private sanitized: DomSanitizer) {}
  transform(value) {
    return this.sanitized.bypassSecurityTrustHtml(value);
  }
}

So you can use it like:

<div [innerHtml]="html | safeHtml"></div>

Plunker Example

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

9 Comments

Awesome solution! The only thing I've changed is I added pure: true to the @Pipe decorator, so that Angular knows not to recalculate it over and over again on every change detection, and does that only if html (the input) is changed. At least that's what I figure should be happening :)
This can open you up to a XSS attack.
Bypassing sanitizer to trust any content can be a security concern. Since Angular is not a dedicated sanitizing library, it is overzealous towards suspicious content to not take any risks. It removed almost all attributes, for example. You can delegate sanitizing to a dedicated library — DOMPurify. Here's a wrapper library I've made to easily use DOMPurify with Angular: github.com/TinkoffCreditSystems/ng-dompurify
This creates security concern. Before implementing this solution, please read @a darren answer!
the pipe name should be unsafeHtml since it will literally let unsafe html to the dom. There is nothing safe in this pipe
|
52

I improved the example of yurzui a bit by completing the needed imports:

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

@Pipe({ name: 'safeHtml'})
export class SafeHtmlPipe implements PipeTransform  {
  constructor(private sanitized: DomSanitizer) {}
  transform(value) {
    return this.sanitized.bypassSecurityTrustHtml(value);
  }
}

I also had to add the class in my app.module.ts file

import ...
import {SafeHtmlPipe} from "./pipes/safehtml.pipe";
@NgModule({
    declarations: [
        AppComponent,
        ...,
        SafeHtmlPipe  <--
    ],
    imports: [...],
    providers: [...],
    bootstrap: [AppComponent]
})
export class AppModule {
}

Comments

16

Note that the sanitizer has a few methods for trusting content e.g.

this.sanitizer.bypassSecurityTrustStyle(value);
this.sanitizer.bypassSecurityTrustHtml(value);
this.sanitizer.bypassSecurityTrustXxx(value); // - see docs [1]

via https://stackoverflow.com/a/41089093/142714

So, bypassSecurityTrustStyle may also be what you want here, as this will show inline styles within your HTML content (value).

[1] docs: https://angular.io/api/platform-browser/DomSanitizer

2 Comments

This should be the accepted answer in my opinion. only using bypassSecurityTrustHtml() is prune to run malicious javascript. If only styles are what you need to bypass, bypass using bypassSecurityTrustStyle() is better.
This should not be the accepted answer, as it is wrong. bypassSecurityTrustStyle returns SafeStyle and [innerHTML] requires SafeHtml. If you use it, it throws: Required a safe HTML, got a Style. So if you have html content with inline styles a combination of an external sanitizer and bypassSecurityTrustHtml() like described in below comment (stackoverflow.com/questions/39628007/…) should be the way to go.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.