使用v-html渲染数据库HTML时如何忽略或移除<base>等危险标签?
风险前置说明
你计划使用String.replace配合正则过滤危险标签的方案不推荐,HTML标签格式变种极多(大小写不敏感、标签内插注释/换行、属性特殊字符转义等),正则很难覆盖所有场景,极易出现过滤遗漏导致风险。
最佳实践:使用成熟的HTML净化工具
优先选择专门针对HTML安全过滤设计的开源净化库,这类工具已经覆盖了几乎所有已知的恶意标签、属性注入、XSS攻击场景,默认会自动移除<base>、<script>等风险标签,也支持自定义过滤规则。
以常用的DOMPurify为例,在Vue项目中使用方式如下:
- 安装依赖
npm install dompurify
- 封装净化逻辑使用
import DOMPurify from 'dompurify' import { computed } from 'vue' // 原始从数据库取的HTML内容 const htmlContent = ref('') // 过滤后的安全内容 const safeHtml = computed(() => { return DOMPurify.sanitize(htmlContent.value, { // 可自定义禁止的标签列表,额外加你需要屏蔽的标签 FORBID_TAGS: ['base', 'script', 'style', 'iframe'], // 也可自定义禁止的风险属性 FORBID_ATTR: ['onclick', 'onload', 'onerror', 'onmouseover'] }) })
- 模板渲染直接使用过滤后的内容即可
<div v-html="safeHtml"></div>
自研过滤替代方案(不推荐,仅做轻量场景参考)
如果不想引入第三方依赖,也不要使用正则,改用浏览器原生DOM API做过滤,准确率远高于正则:
function filterUnsafeTags(rawHtml) { // 定义需要移除的标签集合,注意标签名要大写匹配DOM API返回的tagName const forbidTags = new Set(['BASE', 'SCRIPT', 'STYLE', 'IFRAME']) // 创建脱离当前文档的临时容器,不会影响当前页面运行 const tempContainer = document.createElement('div') tempContainer.innerHTML = rawHtml // 遍历所有层级的节点 tempContainer.querySelectorAll('*').forEach(node => { if (forbidTags.has(node.tagName)) { node.remove() } }) return tempContainer.innerHTML }
该方案仅能过滤整标签风险,无法覆盖属性内的注入风险,仅适合内容来源完全可控的场景。
额外注意事项
v-html本身存在固有安全风险,尽可能只渲染完全可信来源的HTML内容,不要渲染用户可自主提交的富文本内容- 可以根据业务需要尽可能缩小允许的标签、属性范围,不需要的格式权限全部关闭,降低风险面
内容的提问来源于stack exchange,提问作者benams
相关产品推荐
相关产品推荐

