Vue里用innerHTML显示用户评论内容,怎么防止XSS攻击啊?
我在做一个论坛帖子的评论展示功能,用v-html渲染用户提交的内容,但测试时发现能直接执行脚本标签。比如用户输入alert(1),页面真的会弹窗。试过用转义函数替换尖括号,但图片和链接标签也失效了,怎么办?
代码是这样的:
<template>
<div v-for="comment in comments">
<div class="comment-content" v-html="comment.content"></div>
</div>
</template>
<script setup>
import { ref } from 'vue'
const comments = ref([
{ content: '<p>测试内容</p><script>alert(1)</script>' }
])
</script>
用v-html直接显示确实方便,但这样风险太大了。转义后用户输入的格式化标签也没法用了,有没有既能保留HTML格式又安全的方法?
模板里这么写:
<div v-html="sanitizeHtml(comment.content)"></div>。这样既能保留正常的HTML格式,又能过滤掉恶意脚本,省心又靠谱。别再自己写转义函数了,容易漏掉特殊情况,DOMPurify这种库就是干这个的,比你我写的都全。v-html确实方便,但直接渲染用户输入的内容就是个大坑,分分钟被XSS攻击。你提到的转义函数虽然能防住脚本执行,但把正常HTML也干掉了,这事儿得换个思路。推荐用一个叫
dompurify的库,专门清理用户输入的HTML内容,既能去掉危险标签和属性,又能保留正常的格式化内容,比如图片、链接啥的。这样更清晰,安全性也有保障。安装它很简单:
然后在代码里稍微改一下:
DOMPurify.sanitize会自动清理掉危险的部分,比如标签、on*属性这些,同时保留、、![]()
等正常标签。这样既安全又不会影响用户体验。当然了,除了前端防护,后端也得对用户输入做严格校验和清理,双保险才靠谱。别想着单靠前端就能完全挡住攻击,那不现实。