前端如何用安全沙箱防止XSS攻击?
最近在做一个富文本编辑器的功能,用户可以输入HTML内容,但我担心XSS问题。听说可以用沙箱隔离,比如把内容放到iframe里?我试过动态创建iframe然后写入内容,但样式全乱了,而且有些脚本还是能执行。
有没有更靠谱的方案?比如用<iframe sandbox>属性?或者像DOMPurify那样先清洗再渲染?我现在的代码大概是这样:
const iframe = document.createElement('iframe');
iframe.sandbox = 'allow-same-origin';
document.body.appendChild(iframe);
const doc = iframe.contentDocument;
doc.open();
doc.write(userInputHTML); // 这里可能包含恶意脚本
doc.close();
但测试发现如果userInputHTML里有<img src=x onerror=alert(1)>,还是会弹窗,这沙箱好像没起作用?到底该怎么正确实现安全沙箱?
我的做法是这样:先把输入内容用 DOMPurify 清洗一遍,再去渲染。DOMPurify 可以很好地过滤掉危险的脚本和事件处理器。然后 iframe 的 sandbox 属性要这么设置:
注意这里不要加 allow-scripts,避免执行恶意脚本。如果样式乱了,可以考虑在 iframe 里定义基本的 CSS 样式,或者用 shadow DOM 隔离样式。
其实最简单的方案就是直接用 DOMPurify 清洗后再渲染到普通 div 里,不一定非要用 iframe 沙箱。iframe 带来的问题更多,调试也麻烦。
最后提醒一句,永远别相信用户的输入,哪怕是经过清洗的也要保持警惕。我以前就被这个坑过,半夜突然发现线上出了 XSS,真是够喝一壶的。
沙箱属性容易漏掉危险脚本,清洗才是王道。累死人的安全问题啊。