1

I have a custom frontend application built in angular 2 to display the wordpress posts.

I call the rest api as documented to get the post I want

/wp-json/wp/v2/posts/6  

And that gives me the object that I use to populate the page, inside the object is the key content which has all of the content written into the post including all embeded media.

content: {rendered: "<iframe src="xxx"></iframe> lorem ipsum <img src="xxx"/>", protected: false}  

I display it in angular by doing along the lines of

{{data.content.rendered}}  

This will correctly display the text and the images but the iframe wont be rendered and I will get and error in the console.

WARNING: sanitizing HTML stripped some content (see http://g.co/ng/security#xss).  

I read around and some people mentioned the DomSanitizer to fix this, is this the only way possible and what are the security risks of this method.

Alternativly is there any way to modify the wordpress to send back the links embeded in the post in their own key within the object?

edit - after checking out the issue at https://github.com/angular/angular/issues/10145 and using the angular documentation at https://angular.io/api/platform-browser/DomSanitizer, I am still having the issue of the iframe not displaying sadly. The domsanitizer wrapped my display object in another object called changingThisBreaksApplicationSecurity but that didn't display the iframe

Edit 2 - Component

import { Component, OnInit, Input } from '@angular/core';
import {SharedService} from '../services/shared.service';
import {Location} from '@angular/common';
import {Router} from '@angular/router';
import {LocalStorageService} from 
'../services/local.service';
import { ActivatedRoute } from '@angular/router';
import { NgZone } from '@angular/core';
import { ApiService } from '../services/api.service';
@Component({
  selector: 'app-page',
  templateUrl: 'page.template.html',
  styleUrls: ['page.scss'],
  providers: []
})
export class PageComponent implements OnInit {
pageData;
  loading = true;
  private sub: any;
  hide = false;

  constructor(private sharedService: SharedService, private local: LocalStorageService, private api:  ApiService,  private router: Router, private _location: Location) { }

  ngOnInit() {             

         this.pageData = this.sharedService.pageData ?  this.sharedService.pageData : this.local.getItem('pageData')

      if(this.pageData){
             this.api.getWPData(this.pageData.id)
                  .subscribe((data) =>{
                    this.pageData = data;

                    this.loading = false;


                  },
                  err =>{
                    console.log('There was an error please contact the system administrator');
                    this.loading=false;
                  })


  }
  toggleSynopsis = () =>{
       this.hide = !this.hide;
   }
   testfun = () =>{
      this.router.navigate(['/']);
  }
}  

Template

     <div *ngIf="!loading">
     <!-- <app-tiles></app-tiles> -->
    <div class="container main-text" *ngIf="pageData">
        <div class="content">
            <h1 class="title is-1 page-title">{{pageData.title.rendered}}</h1>
            <h2 class="subtitle is-2 page-subtitle">{{pageData.wps_subtitle}}</h2>
            <article class="message is-dark" [ngClass]="{'hidden': hide}">
            <div class="message-header">
                <p>Synopsis</p>
                <button class="delete" aria-label="delete" (click)="toggleSynopsis()"></button>
            </div>
            <div class="message-body" [innerHtml]="pageData.excerpt.rendered">
                <!-- {{pageDate.excerpt.rendered}} -->
            </div>
        </article>
        <p class=" text-body " [innerHtml]="pageData.content.rendered ">
        </p>
    </div>
 </div>
 <app-goback (click)="testfun()"></app-goback>
 <app-footer></app-footer>
 </div> 

Sorry for the formatting im on mobile

1

2 Answers 2

2

After some work I found you can pass the data through multiple of the angular sanitizers. Due to the iframe being in the object I had to first pass it through the bypassSecurityTrustHtml by followed by the bypassSecurityTrustResourceUrl.

import { DomSanitizer, SafeResourceUrl, SafeHtml , SafeUrl} from '@angular/platform-browser';

constructor(public  sanitizer: DomSanitizer)

this.iframeUrl = 
this.sanitizer.bypassSecurityTrustHtml(this.pageData.iframe);
this.iframeUrl = this.sanitizer.bypassSecurityTrustResourceUrl(this.iframeUrl);

after doing that I was able to see the iframe and video.

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

Comments

0

You can try the innerHTML property:

<div [innerHTML]='data.content.rendered'></div>

4 Comments

Hi thanks for the suggestion, I tried that the image still shows fine but the iframe is still not working. *edit - ment to say still getting the same warning, WARNING: sanitizing HTML stripped some content (see g.co/ng/security#xss).
Take a look at this thread: github.com/angular/angular/issues/10145 and this plunker plnkr.co/edit/gQfyf7?p=info with the solution using the DomSanitizationService
after looking at that post and using that with the angular documentation at angular.io/api/platform-browser/DomSanitizer I changed the object using this.sanitizer.bypassSecurityTrustHtml(this.pageData)) and all that seemed to do was wrap the object in another object with the key "changingThisBreaksApplicationSecurity" and still give the error WARNING: sanitizing HTML stripped some content (see g.co/ng/security#xss). and still doesnt show the iframe
Update your post with your code (component and template).

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.