富文本编辑器存储内容后渲染时如何有效拦截XSS攻击?

♫珊珊 阅读 7

我在用Quill编辑器实现富文本功能时遇到问题,用户输入的<script>标签在存储到数据库后仍然会被渲染执行。之前用sanitize-html做了过滤,但发现标签被正常保留,而恶意脚本却没被拦截,这是哪里配置错了?

尝试过这样设置白名单:


const options = {
  allowedTags: [ 'p', 'img', 'br', 'div' ],
  allowedAttributes: {
    'img': ['src']
  }
};
sanitizeHtml(dirty, options);

但测试时输入<div><script>alert(1)</script></div>,渲染后控制台居然弹窗了,这说明过滤逻辑存在漏洞,该怎么调整配置才能彻底阻断脚本执行?

我来解答 赞 3 收藏
二维码
手机扫码查看
1 条解答
Zz雨妍
Zz雨妍 Lv1
你的问题出在对 sanitize-html 的配置上,虽然你定义了白名单标签和属性,但没有处理嵌套的恶意标签。攻击者可以通过将脚本嵌套在合法标签中来绕过过滤规则。比如你提到的 <div><script>alert(1)</script></div><script> 标签被保留了下来。

要彻底阻断 XSS 攻击,需要调整配置并加入额外的防护措施。首先,明确一点:sanitize-html 默认不会移除 <script> 标签,除非你在 allowedTags 中显式禁止它。其次,仅仅依赖白名单是不够的,还需要结合上下文进行更严格的校验。

以下是改进后的代码示例:

const sanitizeHtml = require('sanitize-html');

const options = {
allowedTags: ['p', 'img', 'br', 'div'], // 明确允许的标签
allowedAttributes: {
'img': ['src'] // 允许 img 标签的 src 属性
},
disallowedTagsMode: 'remove', // 将未允许的标签直接移除,而不是转义
allowVulnerableTags: false, // 禁用潜在危险标签(如 script)
};

// 示例输入
const dirty = '<div><script>alert(1)</script></div>';
const clean = sanitizeHtml(dirty, options);

console.log(clean); // 输出:<div></div>


这里的关键点在于:
- 设置 disallowedTagsMode'remove',确保所有不在白名单中的标签被完全移除。
- 确保 allowVulnerableTags 设置为 false,以防止意外允许危险标签。

此外,光靠前端或存储前的过滤是不够的,建议在渲染时也做一层防护。比如在输出到页面时,使用安全的编码方式。如果你用的是模板引擎,可以启用自动转义功能;如果是手动拼接 HTML,可以用类似 DOMPurify 的库进一步净化内容。

最后提醒一下,XSS 防护是个系统工程,除了输入过滤,还要注意 HTTP 响应头的安全配置,比如设置 Content-Security-Policy 来限制脚本执行来源。这样即使有漏网之鱼,也能通过 CSP 阻止恶意脚本运行。

总之,配置好 sanitize-html 是第一步,后续还要结合多层防御机制才能真正降低风险。安全这东西,永远别想着一劳永逸,得时刻保持警惕。
点赞 2
2026-02-17 17:00