sanitizing HTML stripped content and how to deal with it

Posted By :Mahima Gautam |31st October 2019

Everyone must have seen the message for inline HTML into DOM in angular. Yes we want to show trusted message from server or we can inline our constant and svg icons because we simply wants to colourize them.

 

Sanitze and DomSanitizer

 

Angular gives classes for clearing content form various malicious junk

 abstract class Sanitizer {
  abstract sanitize(context: SecurityContext, value: string | {}): string | null
}

abstract class DomSanitizer implements Sanitizer {
  abstract sanitize(context: SecurityContext, value: string | SafeValue): string | null
  abstract bypassSecurityTrustHtml(value: string): SafeHtml
  abstract bypassSecurityTrustStyle(value: string): SafeStyle
  abstract bypassSecurityTrustScript(value: string): SafeScript
  abstract bypassSecurityTrustUrl(value: string): SafeUrl
  abstract bypassSecurityTrustResourceUrl(value: string): SafeResourceUrl
}

 

 Angular make use of concrete private class i.e DomSanitizerImpl while building DOM tree
The service introduces the concept of Safevalue. Actually it is a wrappper class around the string. When the rendere added up the content via binding, whether it be a innerHTML, @HostBinding or src its value goes through sanitize method. If it is received in safeValue, then the underlying string get returned simply. Angular has not been sanitizing library specially. So we can expect that framwork is not taking any risks. The code of SVG gets turn into an empty string, inline styles are removed etc.

 

Proper Safehtml pipe

 

With this DOMPurify a pipe can be made that not only mark values as safe but will actually make them also. We can run it via DOMPurify.sanitize method and can mark it safe with provided context

@Pipe({name: 'dompurify'})
export class NgDompurifyPipe implements PipeTransform {
  constructor(private readonly domSanitizer: DomSanitizer) {}

  transform(
    value: {} | string | null,
    context: SecurityContext = SecurityContext.HTML,
  ): SafeValue | null {
    return this.bypassSecurityTrust(context, DOMPurify.sanitize(value));
  }

  private bypassSecurityTrust(
    context: SecurityContext,
    purifiedValue: string,
  ): SafeValue | null {
    switch (context) {
      case SecurityContext.HTML:
        return this.domSanitizer.bypassSecurityTrustHtml(purifiedValue);
      case SecurityContext.STYLE:
        return this.domSanitizer.bypassSecurityTrustStyle(purifiedValue);
      case SecurityContext.SCRIPT:
        return this.domSanitizer.bypassSecurityTrustScript(purifiedValue);
      case SecurityContext.URL:
        return this.domSanitizer.bypassSecurityTrustUrl(purifiedValue);
      case SecurityContext.RESOURCE_URL:
        return this.domSanitizer.bypassSecurityTrustResourceUrl(purifiedValue);
      default:
        return null;
    }
  }
}

 

DoPurifyDomSanitizer

We can create another class by simply extending DomSanitizer that will delegate sanitizing to DOMPurify. We can start with Sanitizer service and we can use it in both pipe and our DOMSanitizer. Adding token will allow users to set up DOMPurify the way it is need for application.

 

 

@NgModule({
    // ...
    providers: [
        {
            provide: DOMPURIFY_CONFIG,
            useValue: {FORBID_ATTR: ['id']},
        },
    ],
    // ...
})
export class AppModule {}


@Injectable({
    providedIn: 'root',
})
export class NgDompurifySanitizer extends Sanitizer {
    constructor(
        @Inject(DOMPURIFY_CONFIG)
        private readonly config: NgDompurifyConfig,
    ) {
        super();
    }

    sanitize(
        _context: SecurityContext,
        value: {} | string | null,
        config: NgDompurifyConfig = this.config,
    ): string {
        return sanitize(String(value || ''), config);
    }

 

 Now we are aware of how DomSanitizer works and we can no longer mask the issue of inlining arbitary content. Now we can use SVG or server generated messages when we provide style sanitizing function.


About Author

Mahima Gautam

Mahima has a good knowledge of HTML and CSS. She is working as a UI Developer and she loves to dance in her free time.

Request For Proposal

[contact-form-7 404 "Not Found"]

Ready to innovate ? Let's get in touch

Chat With Us