我需要提供诸如codepen.io之类的私人服务。用户必须能够创建包含脚本,样式,内联脚本和内联样式的混合内容(是的,具有很多漏洞的XSS不安全内容)。
我的服务具有iframe和monaco代码编辑器。 如何在没有Angular XSS防御和消毒的情况下将用户生成的html,样式和脚本插入iframe?
我该如何使用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;
}
}
答案 0 :(得分:1)
我遇到了类似的问题。我发现了以下解决方法。
我没有使用angular提供的srcdoc directive
,而是创建了一个自定义指令来将srcdoc attribute
的{{1}}设置为
这是代码
srcdoc.directive.ts
iframe element
按如下所示使用它作为组件html
import { Directive, Input, ElementRef, Renderer2, OnChanges, SimpleChanges } from "@angular/core";
@Directive({
selector : '[app-srcdoc]'
})
export class SrcdocDirective implements OnChanges{
// add data binding to directive itself
@Input("app-srcdoc") source:string;
constructor(private elementRef:ElementRef,private renderer:Renderer2) {}
// update the srcdoc attribute whenever the binding changes
ngOnChanges(changes: SimpleChanges): void {
this.renderer.setAttribute(this.elementRef.nativeElement,"srcdoc",changes.source.currentValue);
}
}
答案 1 :(得分:0)
尝试使用DomSanitizer
调用任何bypassSecurityTrust ... API会禁用Angular内置的传入值清除