绝对路径泄露
最近项目发布进行评审的时候,发现输出的前端代码存在着:泄漏绝对路径漏洞。
解决办法
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 从输出的源码看,代码已经经过压缩,应该是按照生产环境的配置进行打包的了。
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前尚未运行。
3.最终的问题在于如何让DefinePlugin的执行顺序优先于vue-loader
经过代码的跟踪,这应该是属于webpack2的天生的bug,为了避免这种问题出现,
3.1 建议搭建升级webpack4+,直接使用mode来配置生产环境.
3.2 采用vue-cli来构建项目(推荐),可以省去很多的webpack配置傻瓜式使用,让你不用花费太多的时间在webpack的配置当中。
3.2 如果不希望变动太大,可以参考解决办法2
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。