一、问题
当项目中使用了vue中的 v-html 指令时:
<div class="article-content ql-editor" v-html="markdownContent"></div>
进行eslint检查时报如下警告:
warning 'v-html' directive can lead to XSS attack vue/no-v-html
二、什么是XSS?
XSS是跨站脚本攻击(Cross-Site Scripting)的简称。
XSS是一种注入脚本式攻击,攻击者利用如提交表单、发布评论等方式将事先准备好的恶意脚本注入到那些良性可信的网站中。
当其他用户进入该网站后,脚本就在用户不知情的情况下偷偷地执行了,这样的脚本可能会窃取用户的信息、修改页面内容、或者伪造用户执行其他操作等等,后果不可估量。
发送到Web浏览器的恶意内容通常采用JavaScript代码片段的形式,但也可能包括HTML,Flash或浏览器可能执行的任何其他类型的代码。
vue官网对于v-html的描述:
在你的站点上动态渲染任意的 HTML 是非常危险的,因为它很容易导致 XSS 攻击。请只对可信内容使用 HTML 插值,绝不要将用户提供的内容作为插值
例如以下代码:
<template>
<section>
<div v-html='htmlString'></div>
</section>
</template>
<script>
export default {
data() {
return {
htmlString: '<img src="http://www.jpg" οnerrοr="alert('XSS')"/>'
}
}
}
</script>
三、解决办法
1、使用xss模块
下载依赖
npm install xss --save
然后在main.js中引入
import xss from 'xss'
// 定义全局XSS解决方法
Object.defineProperty(Vue.prototype, '$xss', {
value: xss
})
但在实际使用中,需要自定义拦截规则,我们在data中添加如下配置,下面是自定义白名单,也就是什么标签以及标签的属性能够正常使用,其它的都会被拦截
data() {
return {
// xss白名单配置
options : {
whiteList: {
a: ['href', 'title', 'target'],
span: ['class']
}
}
};
},
然后针对需要渲染的页面,调用$xss()方法
<div class="article-content" v-html="$xss(article.content,option)"></div>
2、使用vue-dompurify-html模块
下载依赖
npm install vue-dompurify-html --save
main.js中引入vue-dompurify-html包,并挂载到vue原型上
import VueDOMPurifyHTML from 'vue-dompurify-html'
Vue.use(VueDOMPurifyHTML)
// or Vue3
const app = createApp(App)
app.use(VueDOMPurifyHTML)
使用
<div class="article-content" v-dompurify-html="article.content" />