1
绝对路径泄露

最近项目发布进行评审的时候,发现输出的前端代码存在着:泄漏绝对路径漏洞。
image
image

解决办法

1.检查webpack打包是否正确设置process.env.NODE_ENV。

    //将下面代码放置在webpack的plugins配置中
    new webpack.DefinePlugin({
      'process.env': {
         NODE_ENV: '"production"'
        }
    })

2.在运行webpack之前先执行process.env.NODE_ENV = "production"

//一般项目都会有build.js运行webpak,从build.js可以找到下面类似代码
process.env.NODE_ENV = "production"//新增这行代码
webpack(webpackConfig, function (err, stats) {
    spinner.stop()
    if (err) throw err
    process.stdout.write(stats.toString({
      colors: true,
      modules: false,
      children: false,
      chunks: false,
      chunkModules: false
    }) + '\n\n')
  })

3.直接修改vue-loader源码写死为生产环境。(过于暴力,不推荐)

3.1 将node_modules文件夹里面的“vue-loader”复制到源码根目录。
3.2 修改webpack配置里面vue-loader的路径:
    module: {
        rules: [{
            test: /\.vue$/,
            //loader: 'vue-loader',//修改前
            loader: path.resolve('./vue-loader/index.js'),//修改后
3.3 修改vue-loader源码./vue-loader/lib/loader.js,写死为生产环境:
    //  var isProduction = this.minimize || process.env.NODE_ENV === 'production'//修改前
        var isProduction = true;//修改后
问题原理

1.分析源码

1.1 从输出的源码看,代码已经经过压缩,应该是按照生产环境的配置进行打包的了。
image
1.2 压缩的源码很难发现出问题的地方,那我先取消压缩这个动作。
//分析下面代码,初步定位是vue-loader解析css时输出的代码
var Component = __webpack_require__(9)(
  /* script */
  __webpack_require__(1828),
  /* template */
  __webpack_require__(1830),
  /* scopeId */
  null,
  /* cssModules */
  null
)
Component.options.__file = "C:\\Users\\xxxx\\col.vue"
if (Component.esModule && Object.keys(Component.esModule).some(function (key) {return key !== "default" && key !== "__esModule"})) {
  console.error("named exports are not supported in *.vue files.")
}
if (Component.options.functional) {
  console.error("[vue-loader] col.vue: functional components are not supported with templates, they should use render functions.")
}
1.3 查看vue-loader源码
  //分析源码原则上就是只有生产环境才会输出这些代码。理论上设置好process.env.NODE_ENV应该就不会输出这些代码,初步判断process.env.NODE_ENV没有设置好或没有起作用。
  var isProduction = this.minimize || process.env.NODE_ENV === 'production'
  //...省略多行
  // development-only code
  if (!isProduction) {
    // add filename in dev
    output += 'Component.options.__file = ' + JSON.stringify(filePath) + '\n'
    // check named exports
    output +=
      'if (Component.esModule && Object.keys(Component.esModule).some(function (key) {' +
        'return key !== "default" && key !== "__esModule"' +
      '})) {' +
        'console.error("named exports are not supported in *.vue files.")' +
      '}\n'
    // check functional components used with templates
    if (template) {
      output +=
        'if (Component.options.functional) {' +
          'console.error("' +
          '[vue-loader] ' + fileName + ': functional components are not ' +
          'supported with templates, they should use render functions.' +
        '")}\n'
    }
  }
1.4 写死生产环境,编译输出(使用解决办法3
从输出结果看,这次打包已经满足打包需求,能够解决漏洞了,但本质问题尚未解决。
为什么process.env.NODE_ENV配置不起作用?

2.初步解决办法
既然DefinePlugin配置process.env.NODE_ENV不起作用,那么就通过代码写死来配置吧.

(如上文提及的:解决办法2 在运行webpack之前先执行process.env.NODE_ENV = "production")

3.为什么DefinePlugin配置process.env.NODE_ENV不起作用
通过在生产代码输出,可知DefinePlugin已经起作用了,只是在执行vue-loader前尚未运行。
image

3.最终的问题在于如何让DefinePlugin的执行顺序优先于vue-loader
经过代码的跟踪,这应该是属于webpack2的天生的bug,为了避免这种问题出现,
3.1 建议搭建升级webpack4+,直接使用mode来配置生产环境.
3.2 采用vue-cli来构建项目(推荐),可以省去很多的webpack配置傻瓜式使用,让你不用花费太多的时间在webpack的配置当中。
3.2 如果不希望变动太大,可以参考解决办法2


Jillsion
3 声望0 粉丝