Angular 7 DOM дезинфекция смешанного содержимого - PullRequest
0 голосов
/ 06 декабря 2018

Мне нужно сделать частный сервис, как codepen.io.Пользователь должен иметь возможность создавать смешанный контент с включенными скриптами, стилями, встроенными скриптами и встроенными стилями (да, небезопасный контент XSS с множеством уязвимостей).

Снимок экрана службы

В моем сервисе есть редактор iframe и monaco. Как мне вставить пользовательский html, стили и скрипты в iframe без Angular XSS-защиты и очистки?

Как мне это сделать с Angular 7?

Может быть, существует способ пометки вручную сгенерированного пользователем контента как санированного?

Важные фрагменты кода.

view.component.html :

<iframe id="view" [srcdoc]="resultPage | safe: 'html'"></iframe>

view.component.ts :

@Component({
  selector: 'app-view',
  templateUrl: './view.component.html',
  styleUrls: ['./view.component.scss']
})
export class ViewComponent implements OnInit {

  resultPage = '';

  _task: Task;
  set task(value: Task) {
    this._task = value;
    if (value) {
      this.refreshPage();
    }
  }
  get task() {
    return this._task;
  }

  constructor(private store: Store<RootStoreState.State>) { }

  ngOnInit() {
    this.store.pipe(select(selectSelectedTask))
      .subscribe((task) => {
        this.task = task;
      });
  }

  refreshPage() {
    if (!this.task) {return; }
    const htmlFile = this.task.files.find((item) => item.language === 'html')
    const cssFile = this.task.files.find((item) => item.language === 'css')
    const jsFile = this.task.files.find((item) => item.language === 'js')
    let html = htmlFile ? htmlFile.content : null;
    if (!html) {
      return;
    }
    let css = cssFile ? cssFile.content : null;
    let js = jsFile ? jsFile.content : null;
    html = this.insertCss(html, css);
    this.resultPage = html;
  }

  insertCss(html: string, css: string): string {
    const cssPlaceholder = `<style>${css}</style>`;
    const closedHead = html.indexOf('</head>');
    if (closedHead > -1) {
      html.replace('</head>', cssPlaceholder + '</head>');
      console.log(1, html);
      return html;
    }
    const openedBody = html.indexOf('<body>');
    if (openedBody > -1) {
      html.replace('<body>', '<body>' + cssPlaceholder);
      console.log(2, html);
      return html;
    }
    html += css;
    console.log(3, html);
    return html;
  }

}

1 Ответ

0 голосов
/ 06 декабря 2018

Попробуйте использовать DomSanitizer

Вызов любого из API-интерфейсов bypassSecurityTrust ... отключает встроенную очистку Angular для значения, переданного в

...