没有进行防止xss攻击的例子
<p v-html="test"></p>
export default {
data () {
return {
test: `<a οnclick='alert("xss攻击")'>链接</a>`
}
}
结果,js事件被执行,弹出弹框,我们要杜绝这种情况,保留a标签,拦截onclick事件
解决办法
法一:
使用一个xss的npm包来过滤xss攻击代码,给指令的value包上一层xss函数
npm install xss --save
import xss from 'xss'
<p v-html="$xss(test)"></p>
import xss from 'xss'
export default {
data () {
return {
test: `<a οnclick='alert("xss攻击")'>链接</a>`
}
}
Object.defineProperty(Vue.prototype, '$xss', {
value: xss
})
法二:
在业务代码里使用xss函数处理,不能保证团队每一个成员都会使用xss函数处理,作为前端的架构师,我们需要从项目整体的考虑来处理这类问题,不能指望通过规范来约束团队成员
1.引入xss包并挂载到vue原型上
import xss from 'xss';
Vue.prototype.xss = xss
2.在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;
});
}
在编译前会将我们从vue-loader传入的compilerOptions.directives和baseOptions.directives进行合并。 这样我们就能覆盖html指令。