项目中某处使用了vue中的 v-html 指令

<div v-if="item.description" class="description" v-html="item.description" />

提交代码进行eslint 检查时报如下警告

15:58  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 攻击]。只在可信内容上使用 v-html永不用在用户提交的内容上。

详细原理见:https://blog.csdn.net/lingxiaoxi_ling/article/details/105851736

简单模拟一个:

<template>
	<section>
    	<div v-html='htmlString'></div>
    </section>
</template>

<script>
export default {
  components: {
  },
  data() {
    return {
      htmlString: '<img src="http://www.jpg" οnerrοr="alert(2021)"/>'
    }
  }
}
</script>

运行之后由于src地址对应的资源找不到,会触发img标签的error事件,最终alert弹框。这便是一个最简单的xss攻击。

解决方案两种,推荐法1:

法1:vue-dompurify-html
1. 下载依赖
npm install vue-dompurify-html --save
#or
yarn add vue-dompurify-html
2. main.js中引入 vue-dompurify-html 包并挂载到vue原型上
import VueDOMPurifyHTML from 'vue-dompurify-html'
Vue.use(VueDOMPurifyHTML)
// or Vue3
const app = createApp(App)
app.use(VueDOMPurifyHTML)
3. 使用
<div v-if="item.description" class="description" v-dompurify-html="item.description" />
法2:xss
1. 下载依赖
npm install xss --save
#or
yarn add xss
2. main.js中引入xss包并挂载到vue原型上
import xss from 'xss'
Vue.prototype.xss = xss
3. 在vue.config.js中覆写html指令
  chainWebpack: config => {
    config.module
      .rule('vue')
      .use('vue-loader')
      .loader('vue-loader')
      .tap(options => {
        options.compilerOptions.directives = {
          html(node, directiveMeta) {
            (node.props || (node.props = [])).push({
              name: 'innerHTML',
              value: `xss(_s(${directiveMeta.value}))`
            })
          }
        }
        return options
      })
  }
法3:使 eslint 校验忽略此警告

若是陈年老代码,没有时间去看之前的页面,为什么需要用到v-html。那么我们通过修改eslint的规则去忽略v-html警告。

参考该链接:https://eslint.vuejs.org/rules/no-v-html.html
只要在你的.eslintrc.js文件下的rules对象加入"vue/no-v-html":“off” 即可

"vue/no-v-html":"off" 
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐