0%

webpack带来的安全风险

webpack:

什么是webpack:

webpack用于编译JavaScript模块。

关注javascript技术的同学一定知道,在CommonJS和ES6中,为了支持模块化,而引入了export/require/import这类东西,模块化可以降低开发的复杂度,用于支撑前端的复杂功能,但是模块化后,也带来了许多问题,比如老版本的浏览器不支持ES6/JSX语法,开发和线上不能保持一致,这就为WebPack类的自动化代码转换工具的出现提供了需求。

WebPack可以看做是模块打包机:它做的事情是,分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript等),并将其转换和打包为合适的格式供浏览器使用。

按照官网的说法,webpack可以打包一切资源/图片/样式/依赖等等,webpack默认只支持js模块打包,对于其他文件就需要用loader解析器,比如在vue中,直观的效果就是使用webpack可以将使用的vue,css,图片等打包成一个js。

20200414114758


Source Map:

部署前端之前,开发者通常会对代码进行打包压缩,这样可以减少代码大小,从而有效提高访问速度。然而,压缩代码的报错信息是很难Debug的,因为它的行号和列号已经失真。这时就需要Source Map来还原真实的出错位置了。

为啥变换代码?

前端代码越来越复杂的情况下,开发者通常会使用webpack、UglifyJS2等工具对代码进行打包变换,这样可以减少代码大小,有效提高访问速度。关于变换代码的原因,这里不妨引用一下大神阮一峰的JavaScript Source Map 详解:

  • 压缩,减小体积。比如jQuery 1.9的源码,压缩前是252KB,压缩后是32KB。

  • 多个文件合并,减少HTTP请求数。

  • 其他语言编译成JavaScript。最常见的例子就是CoffeeScript。

如何变换代码?

下面是一个简单的“hello World”程序hello.js

1
2
3
4
5
6
7
8
function sayHello()
{
var name = "Fundebug";
var greeting = "Hello, " + Name;
console.log(greeting);
}

sayHello();

使用UglifyJS2对源代码进行压缩变换:

1
2
3
4
uglifyjs hello.js \
-m toplevel=true \
-c unused=true,collapse_vars=true \
-o hello.min.js

压缩后的代码hello.min.js

1
function o(){var o="Hello, "+Name;console.log(o)}o();

为啥需要Source Map?

使用Firefox执行hello.js的报错信息是这样:

1
2
3
ReferenceError: Name is not defined
sayHello file:///Users/fundebug/sourcemap-tutorial/hello.js:4:9
<匿名> file:///Users/fundebug/sourcemap-tutorial/hello.js:8:1

hello.min.js的报错信息是这样:

1
2
3
ReferenceError: Name is not defined
o file:///Users/fundebug/sourcemap-tutorial/hello.min.js:1:18
<匿名> file:///Users/fundebug/sourcemap-tutorial/hello.min.js:1:59

对比压缩前后的出错信息,我们会发现,错误行号和列号已经失真,且函数名也经过了变换。而对于真实的前端项目,开发者会将数十个源文件压缩为一个文件,这时,错误的列号可能多达数千,且出错的真实文件名也是很难确定的,这样的话,压缩代码的报错信息是很难Debug的。

而Source Map则可以用于还原真实的出错位置,帮助开发者更快的Debug。


webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。

source-map文件,这个文件是编译过程中变量与方法的映射表。


VUE/REACT开发场景

在VUE/REACT开发场景下 ,前端开发会引入如模块化等诸多新特性,前端开发不再是几个简单的js文件,开发完成后会通过webpack等打包工具打包生成部署使用的js文件,但是如果我们直接分析该编译的js,很难看懂。

比如某页面下的app.bundle.js,反正我是看不懂写的是啥,这个js文件就是webpack打包后的结果,但是由于我是开启了source-map调试模式,如果你是用chrome浏览器打开的,打开devtools-sources,应该可以看到一个webpack://,这个就是chrome对source-map调试的支持,点开src目录下就可以看到js代码源文件。

20200414115217

为什么会有这类问题?

大多数开发人员没有意识到的是,这些源映射source-map实际上包含了其前端源代码的全部。

是的,他们知道可以进行映射,但是源映射后的文件几乎为乱码,更不用说理解了。由于这种误解,发现开发团队在其Webpack配置中将JavaScript源映射留在生产环境中是相对常见的。


解决方案:

修改config/index.js中的build对象productionSourceMap: false即可

20200418144413


渗透思路or危害:

  • 通过source-map可以获取前端源码,也就是说从黑盒变成了灰盒。

  • 泄露的各种信息如网站路径、API、加密算法、管理员邮箱、内部功能等等。

  • 很多vue应用都是先渲染页面再判断是否登陆,根据这个小缺陷,我们首先可以查看相关功能

  • 前端源码被人copy走


工具:

unwebpack-sourcemap

通过查看浏览器中包含的JavaScript文件并提取捆绑的JavaScript文件底部存在的sourceMappingURL来获取源地图。

原理:

在页面正则匹配 regex = "\\/\\/#\s*sourceMappingURL=(.*)$"


refs: