Angular 2, DomSanitizer, bypassSecurityTrustHtml, SVG
Asked Answered
S

4

38

I've been using DomSanitizer with an SVG in an html string.

Previous to the current version of Angular, this worked just fine:

this.domSanitizer.bypassSecurityTrustHtml(content);

Now I am getting an object back called

SafeHtmlImpl {changingThisBreaksApplicationSecurity: "<svg> blah </svg>"}
changingThisBreaksApplicationSecurity

Is there now a new way to access the output of the DomSanitizer? Should I be receiving it as SafeHTML type or something? What's the point in having bypassSecurityTrustHtml if it still filters html?

Any answers on a postcard? Please...

Starryeyed answered 4/10, 2016 at 16:55 Comment(2)
So what's the problem?Indemonstrable
@Indemonstrable For some reasons it requires property binding innerHTML="myData | pipeName" and does not work like this innerHTML="useSanitizerFunc(myData)"Reproduction
I
55

DEMO : https://plnkr.co/edit/Qke2jktna55h40ubUl8o?p=preview

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

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

@Component({
  selector: 'my-app',
  template: `
    <div [innerHtml]="html | safeHtml">
    </div>
  `,
})
export class App {
  name:string;
  html: safeHtml;
  constructor() {
    this.name = 'Angular2'
    this.html = "<svg> blah </svg>";
  }
}
Indemonstrable answered 4/10, 2016 at 17:8 Comment(10)
I have changed your svg to other svg to make it work.Indemonstrable
Thanks. good idea about the pipe, I've set it up like that and works. Not actually doing anything functionally different but who's complaining? It works.Starryeyed
Who is complaining means?Indemonstrable
It means I'm not complaining! Thanks for the helpStarryeyed
If it solves the problem, accept answer so future reader will be able to get help.Indemonstrable
Done. Thanks for helpStarryeyed
This does not work when the SVG contains attributes that will be dynamically updated e.g. [attr.fill]="getColor()" instead of attr.fill="yellow" e.g. plnkr.co/edit/dCJEomWsXqOYG181iUus?p=previewDictatorship
I am also having same issue, functions are not calling, just binding the html objects.Seppuku
Does the sanitizers still works in angular 7? I am trying to load a script and it get shown but it does not get executed...Pancreatin
Because SVG can pose a security threat, it is highly recommended to sanitize the SVG beforehand. E.g. using github.com/cure53/DOMPurifyAttenuate
B
1

For that issue you can visit here

We can add custom sanitized pipe and use globally. If your HTML is not sanitized properly then inner html ignore svg, third party url etc. so we can fix it like below:

hero.component.html:

<div [innerHTML]="htmlString | sanitizedHtml"></div>

hero.component.ts

import { Component, OnInit } from '@angular/core';

@Component({
    selector: 'app-hero',
    templateUrl: './hero.component.html',
    styleUrls: ['./hero.component.css']
})
export class HeroComponent implements OnInit {
    htmlString: any;

    constructor() { }

    ngOnInit(): void {
        this.htmlString = `
        <div class="container">
            <header class="blog-header py-3">
            <div class="row flex-nowrap justify-content-between align-items-center">
                <div class="col-4 pt-1">
                <a class="text-muted" href="#">Subscribe</a>
                </div>
                <div class="col-4 text-center">
                <a class="blog-header-logo text-dark" href="#">Large</a>
                </div>
                <div class="col-4 d-flex justify-content-end align-items-center">
                <a class="text-muted" href="#">
                    <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="mx-3"><circle cx="10.5" cy="10.5" r="7.5"></circle><line x1="21" y1="21" x2="15.8" y2="15.8"></line></svg>
                </a>
                <a class="btn btn-sm btn-outline-secondary" href="#">Sign up</a>
                </div>
            </div>
            </header>
        </div>`;
    }
}

sanitized-html.pipe.ts

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

@Pipe({
    name: 'sanitizedHtml'
})
export class SanitizedHtmlPipe implements PipeTransform {
    constructor(private sanitized: DomSanitizer) {}

    transform(value: any): any {
        return this.sanitized.bypassSecurityTrustHtml(value);
    }
}

Output: enter image description here

Botvinnik answered 15/7, 2021 at 13:14 Comment(1)
Careful, with bypassSecurityTrustHtml you are not sanitizing your html but the name of your pipe is implying that you are! You should call it "UnsafeHtmlPipe" or run it through DomSanitizer.sanitize() if possible!Flawed
S
0

Use DomSanitizer.bypassSecurityTrustHtml:

constructor(private sanitizer: DomSanitizer) {
}

let html = this.sanitizer.bypassSecurityTrustHtml("<svg> blah </svg>");

More information: https://angular.io/docs/ts/latest/guide/security.html#bypass-security-apis

Sublimate answered 4/10, 2016 at 17:0 Comment(3)
This is what the OP stated that he is using in his question.Toon
this worked for me in my current version. My issue wasn't what OP stated but I got what I came looking for. Many solutions suggested to use @Pipe and adding DOMSanitizer safeHTML but that's what I wanted to try last. With your solution, I was able to use DomSanitizer within my component file. Thanks Andrei.Sectorial
Literally this is exactly what the OP says he is doing, and that it is not working...Cline
C
0

This can also be done via object bracket notation:

let safeHtml = this.domSanitizer.bypassSecurityTrustHtml(content);
console.log(safeHtml["changingThisBreaksApplicationSecurity");

Had to do this because safeHtml.changingThisBreaksApplicationSecurity didn't work for me.

Connolly answered 12/8, 2020 at 17:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.