阿西河

所有教程

公众号
🌙
阿西河前端的公众号

我的收藏

    最近访问  (文章)

      教程列表

      抓包专区
      测试专区

      Vue.js v-html

      v-html

      • 预期string

      详细

      更新元素的 innerHTML

      注意:内容按普通 HTML 插入 - 不会作为 Vue 模板进行编译

      如果试图使用 v-html 组合模板,可以重新考虑是否通过使用组件来替代。

      在网站上动态渲染任意 HTML 是非常危险的,因为容易导致 XSS 攻击。只在可信内容上使用 v-html永不用在用户提交的内容上。

      单文件组件里,scoped 的样式不会应用在 v-html 内部,因为那部分 HTML 没有被 Vue 的模板编译器处理。如果你希望针对 v-html 的内容设置带作用域的 CSS,你可以替换为 CSS Modules 或用一个额外的全局 <style> 元素手动设置类似 BEM 的作用域策略。

      示例

      <div v-html="html"></div>
      

      参考

      数据绑定语法 - 插值

      xss 攻击演示

      <template>
          <div id='app'>
              <div v-html='html'></div>
          </div>
      </template>
      <script>
      export default {
          name:"app",
          data(){
              return {
                  html:'<img src="https://www.axihe.com" onerror="alert(666)">'
              }
          }
      }
      </script>
      

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

      解决 html 指令存在的 xss 漏洞问题

      通常我们处理 xss 攻击会使用一个 xss 的 npm 包来过滤 xss 攻击代码。

      所以我们要做的就是给指令的 value 包上一层 xss 函数。有同学可能会问,我们在业务代码里使用 xss 函数处理也行。是的可以,但是我们不能保证团队每一个成员都会使用 xss 函数处理。

      作为前端的架构师,我们需要从项目整体的考虑来处理这类问题,不能指望通过规范来约束团队成员。

      在编译前会将我们从 vue-loader 传入的 compilerOptions.directives 和 baseOptions.directives 进行了合并。

      这样我们就能覆盖 html 指令。

      1. 引入 xss 包并挂载到 vue 原型上
      import xss from 'xss';
      Vue.prototype.xss = xss
      
      1. 在 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;
              });
      }
      
      

      这样我们就从源头解决了 html 指令存在的潜在 xss 攻击。

      具体参考参考:https://juejin.im/post/5d5924a0e51d4561fc620a46

      可能存在的问题

      此外某些情况下,使用{{{}}}符号仍然不能解析 html 标签,但 v-htm 指令却可以,可能是 Vue.js 存在的 bug 。

      参考:https://blog.csdn.net/farYang/article/details/53011703

      其它参考

      目录
      目录