Webpack源代码泄露漏洞研究

本文最后更新于 2024年10月22日 晚上

Webpack源代码泄露漏洞研究

Webpack简介

Webpack 是一个用于现代JavaScript应用的模块打包器(module bundler)。它的主要功能是将项目中的各种资源(JavaScript、CSS、图片等)作为模块进行管理和打包,生成一个或多个bundle文件,以提高项目的加载和运行效率

Webpack功能

简单看一眼就行,不用做细致研究:

1. 模块打包(Module Bundling)

将多个模块及其依赖项打包成一个或多个bundle文件,优化加载性能。

2. 代码拆分(Code Splitting)

将代码拆分为多个小块,以便按需加载,减少初始加载时间,提高应用程序性能。

3. 加载器(Loaders)

允许Webpack处理非JavaScript文件(如CSS、图片、TypeScript等),并将它们转换为Webpack可以理解的模块,增强了对多种资源的支持。

4. 插件(Plugins)

扩展Webpack的功能,执行各种任务,如打包优化、资源管理和注入环境变量等,使得构建过程更加灵活和强大。

5. 热模块替换(Hot Module Replacement, HMR)

允许在应用程序运行时替换、添加或删除模块,而无需完全刷新页面,提高开发效率和用户体验。

6. 样式和资源文件处理

处理和打包CSS、图片、字体等资源文件,确保它们能与JavaScript文件一起正常加载和使用。

7. 样式提取(CSS Extraction)

将CSS从JavaScript文件中提取出来,生成独立的CSS文件,优化样式的加载和管理。

8. Tree Shaking

通过消除未使用的代码来减小打包后的文件大小,优化应用程序性能。

9. 开发服务器(DevServer)

提供一个本地开发服务器,支持热加载和实时刷新,简化开发过程。

10. 环境配置

根据不同的构建环境(如开发环境和生产环境)进行配置,自动启用相应的优化选项。

Webpack 架构

简单看一眼就行,不用做细致研究:

1. Entry(入口模块):

  • Webpack 从指定的入口模块开始,创建一个模块依赖图。每个模块可以是 JavaScript 文件、CSS 文件、图像文件等。

2. Dependency Graph(依赖图):

  • Webpack 解析每个模块的依赖项,并将这些依赖项添加到依赖图中。依赖图描述了模块之间的依赖关系。

3. Loaders(加载器):

  • 在解析模块时,Webpack 使用加载器将不同类型的文件转换为可以添加到依赖图中的模块。例如,babel-loader 将 ES6 转换为 ES5,css-loader 将 CSS 文件转换为 JavaScript 模块。

4. Plugins(插件):

  • Webpack 插件提供了一种机制来扩展 Webpack 的功能。插件可以在整个构建过程中的各个阶段执行特定任务,如优化打包、注入环境变量、压缩代码等。

5. Output(输出模块):

  • Webpack 将依赖图中的所有模块打包到一个或多个输出文件中,并将这些文件输出到指定的目录。

6. 示例 Webpack 配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
javascript复制代码const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
},
mode: 'development',
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
},
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
],
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
}),
],
};

Webpack对测试带来的阻碍

1. 代码混淆和压缩

  • Webpack通常会对JavaScript代码进行混淆和压缩,使得代码难以阅读和理解。
  • 这增加了逆向工程和代码审计的难度,安全测试人员很难追踪到具体的漏洞位置或理解代码的逻辑。

2. 动态模块加载

  • Webpack支持动态导入模块,允许在运行时按需加载代码。
  • 动态加载的代码片段可能不会在初始页面加载时暴露出来,安全测试人员需要模拟特定的用户行为才能触发这些代码,增加了测试复杂性。

3. 模块化和依赖管理

  • Webpack将项目中的各个文件模块化,创建了复杂的依赖关系图。
  • 安全测试人员需要理解和分析这些模块之间的依赖关系,识别潜在的安全漏洞,这比分析单一文件的传统应用程序要复杂得多。

4. 热模块替换(HMR)

  • Webpack的热模块替换功能允许在不刷新页面的情况下替换、添加或删除模块。
  • 这可能会导致在动态内容更新过程中出现安全漏洞,安全测试人员需要特别关注这些动态更新的模块。

5. 资源文件的处理

  • Webpack不仅处理JavaScript文件,还处理CSS、图片等其他资源文件。
  • 这些非JavaScript资源文件的打包和加载方式可能会引入额外的安全风险,例如CSS注入或文件上传漏洞,测试人员需要额外关注这些资源文件的处理方式。

6. Source Maps

  • 虽然Source Maps可以帮助调试,但在生产环境中通常会被禁用或混淆。
  • 缺乏Source Maps使得逆向工程和调试变得更加困难,安全测试人员难以还原和理解混淆后的代码。

Webpack源代码泄露漏洞

1. 漏洞成因

Webpack 会为打包后的代码生成 Source Map 文件,以便在运行时可以调试源代码。然而,如果开发人员在生产环境中没有正确地配置 SourceMap,攻击者就可能获得敏感信息,例如源代码和服务器配置等。

漏洞配置:

(1) 在生产环境中开启 SourceMap 功能:

1
2
3
4
5
// webpack.config.js
module.exports = {
// ...
devtool: 'source-map',
};1.2.3.4.5.

(2) 配置 Web 服务器,以便通过 HTTP 获取 SourceMap 文件:

1
2
3
4
5
6
# nginx configuration
location /static/ {
add_header 'Access-Control-Allow-Origin' '*';
# 设置为源映射文件所在的目录
alias '/path/to/source-maps/';
}

2. 漏洞发现

(1) 直接F12控制台查看source

F12->Sources—> Page—> Webpack://

在源代码面板可能直接看到webpack的目录,直接泄露了前端源代码

image

一般的源代码查看:通过 F12 查看的是压缩和混淆后的代码,通常难以阅读和理解,且通常不会包含敏感信息。

Webpack 项目源码泄漏:通过 Webpack:// 查看的是未压缩和未混淆的原始源代码,易于阅读和理解,且可能包含敏感信息和注释。

(2) 寻找.js.map文件

.js.map 文件包含了从压缩和混淆后的代码到原始源代码的映射关系,能够帮助攻击者理解和分析网站的源代码。通过 Source Map 文件,攻击者可以反向映射回原始的源代码,查看详细的代码逻辑和实现细节。这可能会暴露敏感信息,如 API 密钥、配置参数、业务逻辑、以及开发者注释等。

寻找方式

  • F12看js源码结尾处,或者全局搜索.js.map

image

Ctrl+Shift+F

image

  • burp抓包寻找,同理
  • FindSomeThing插件

image

3. 工具推荐

(1) Packer-Fuzzer

https://github.com/rtcatc/Packer-Fuzzer

image

image

(2) SourceDetector

SourceDetector是一个谷歌浏览器插件,此插件可以自动的判断网站是否存在js.map文件,并且能够利用该插件直接下载到js.map的webpack项目源码

image

image

(3) reverse-sourcema

  • 安装工具
1
npm install --global reverse-sourcemap
  • 工具安装后,将网站 js.map 下载保存到一个文件夹内,使用该工具还原(以还原主 js.map 源码为例)
1
reverse-sourcemap --output-dir ./001 app.d61xxxxxxx7a4d0aa777.js.map

image

如果需要审计分析全部源码,则将网站所有 js.map 下载保存到本地文件夹内,配合使用 -v 参数指定所存放 js.map 文件夹路径,即可根据文件夹内所有 js.map 还原源码。

漏洞利用

  • 寻找敏感信息 password mail phone sfz key token 加密算法等等
  • 寻找隐藏的api
  • JS代码审计
  • ……

漏洞防御与修复

1. 禁用生产环境的 Source Map

  • 在生产环境中禁用 Source Map 生成,防止源码泄露。
1
2
3
4
5
javascript复制代码// webpack.config.js
module.exports = {
mode: 'production',
devtool: false, // 禁用 source map
};

2. 使用安全的 Source Map 类型

  • 在开发环境中使用安全的 Source Map 类型,如 eval-source-map
1
2
3
4
5
javascript复制代码// webpack.config.js
module.exports = {
mode: 'development',
devtool: 'eval-source-map',
};

3. 环境变量管理

  • 将敏感信息存储在环境变量中,而不是代码中。
1
2
javascript复制代码require('dotenv').config();
const apiKey = process.env.API_KEY;

4. 最小化代码暴露

  • 减少公开代码中暴露的敏感信息和 API,确保代码安全