5

I used DomSanitizer to sanitize my HTML content from database to be displayed on page.

<div [innerHtml]="safeHtml(article.text)"></div>

Where safeHtml is:

safeHtml(html){
    return this.sanitize.bypassSecurityTrustHtml(html);
}

It works perfect. But I've noticed that this text cannot be selected nor copied when displayed on web page. Otherwise, the texts displayed from normal string field can be copied or selected normally.

Vlada Veljkovic
  • 141
  • 1
  • 6
  • For everyone who may have similar issue in the future, solution is to use pipe. Instead upper function safeHtml(article.text) which returns particular DOMSanitizer method, the custom pipe should be used (ex. article.text | safeHtml - where safeHtml is custom pipe using DOMSanitizer) – Vlada Veljkovic Dec 09 '19 at 14:43
  • I am using a pipe, and have the same issue with selecting text. – Binary Alchemist Feb 25 '20 at 16:47

2 Answers2

5

At first glance bypassSecurityTrustHtml() looks to be want we want, but the documentation warns against using this method general. Assuming the content from the database does not contain <script> bypassSecurityTrustHtml is the wrong method. It can also cause the text from the inserted html to not be selected/copied.

Bypass security and trust the given value to be safe HTML. Only use this when the bound HTML is unsafe (e.g. contains tags) and the code should be executed. The sanitizer will leave safe HTML intact, so in most situations this method should not be used.

<div [innerHtml]="article.text | keepHtml"></div>
import { Pipe, PipeTransform, SecurityContext } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';

@Pipe({ name: 'keepHtml', pure: false })
export class EscapeHtmlPipe implements PipeTransform {
    constructor(private sanitizer: DomSanitizer) {}

    transform(content) {
        return this.sanitizer.sanitize(SecurityContext.HTML, content);
    }
}

In specific situations, it might be necessary to disable sanitization, for example if the application genuinely needs to produce a javascript: style link with a dynamic value in it. Users can bypass security by constructing a value with one of the bypassSecurityTrust... methods, and then binding to that value from the template.

These situations should be very rare, and extraordinary care must be taken to avoid creating a Cross Site Scripting (XSS) security bug!

When using bypassSecurityTrust..., make sure to call the method as early as possible and as close as possible to the source of the value, to make it easy to verify no security bug is created by its use.

It is not required (and not recommended) to bypass security if the value is safe, e.g. a URL that does not start with a suspicious protocol, or an HTML snippet that does not contain dangerous code. The sanitizer leaves safe values intact.

sanitize()

If value is trusted for the context, this method will unwrap the contained safe value and use it directly. Otherwise, value will be sanitized to be safe in the given context, for example by replacing URLs that have an unsafe protocol part (such as javascript:). The implementation is responsible to make sure that the value can definitely be safely used in the given context.

Binary Alchemist
  • 1,600
  • 1
  • 13
  • 28
0

Can you please check your HTML content coming from the database. It might be having some style element in it, which might have CSS property user-select:none;.

If this doesn't solve your issue please check the CSS of the container div element.

  • No, not that. Thank you for suggestion, but it seams that this is not CSS issue. This div has the same properties and values as other selectable elements – Vlada Veljkovic Nov 11 '19 at 14:31