Webpack介绍与漏洞成因

Webpack是一个JavaScript应用程序的静态资源打包器(module bundler)。它会递归构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个bundle。

简单来说就是,Webpack是一个前端代码打包工具,它可以将多个JavaScript、CSS、图片等静态资源文件打包成一个或多个静态资源文件并通过模块化管理打包后的代码以提高前端应用程序的性能和加载速度

Webpack目前支持很多种调试模式,每种模式的区别是编译后的代码和源码的映射方式不同。比如,有的模式会生成一个.map文件映射,有的模式会通过注释映射,有的模式会使用DataUrl的方式映射。更具体的,见下图

image-20240706151602794

Webpack源代码泄露漏洞针对的就是【通过生成一个.map文件映射】的这种模式,使用Webpack打包应用程序会在网站js同目录下生成js.map文件。.map文件的作用是:项目打包后,代码都是经过压缩加密的,如果运行时报错,输出的错误信息无法准确得知是哪里的代码报错,而有了.map之后,就可以像未加密的代码一样,准确的输出是哪一行哪一列有错,方便开发者调试。开发者会在开发时,在webpack.config.js中可以通过设置devtool选项来开启Source Map功能:

// webpack.config.js
module.exports = {
  // ...
  devtool: 'source-map',
};

所以如果开发者部署到线上没有关闭source-map配置,那么我们就可以如开发者一样调试js代码。

更具体的,关于.map文件(或者说Source Map)的作用,这里借用阮一峰师傅的文章做一个说明,如下

image-20240706170346466

image-20240706170432896

漏洞识别

首先要做Webpack站点识别,可以通过Wappalyzer插件检测一下前端技术,如下

image-20240706151111040

确定是Webpack站点后,可以根据以下特征识别

  • 浏览器开发者工具中的Sources–> Page中存在 Webpack://

    image-20240706162507527

  • 查看源代码:由于Webpack打包工具所生成的网站大部分会简化掉大量的HTML代码,采用js文件进行页面渲染,前端的所有内容都依赖于浏览器对js文件的解析,所以查看首页源代码如果看到全是js文件,那么大概率该站使用Webpack打包生成,如下图所示

    image-20240706162917164

  • 使用开发者工具检索全部js文件,查找是否存在如下关键字:

    • Webpack所生成的每个js文件具体内容均以webpackJsonp开头

      image-20240706163238838

    • 存在*.js.map文件

    • SourceMap

      image-20240706163115933

  • 大部分Vue等应用项目会使用Webpack进行打包

    Vue框架的一个典型特征就是,URL中带有#符号,比如/index.html#/

漏洞利用

Webpack项目源码在泄漏的情况下,可以在浏览器开发者工具中的Sources–> Page–> Webpack://中查看源代码,如下

image-20240706154023022

在某些情况下,不能直接在浏览器开发者工具中的Sources–> Page–> Webpack://中查看到Webpack项目源码(比如有些前端应用虽然是通过Webpack打包的,但由于关闭了Source Map,所以无法正常显示),但是网站上存在.js.map文件,我们可以通过一些工具将js.map中的内容进行还原Webpack项目源码,效果如下:

image-20240706155218403

image-20240706155253446

工具如下:

获取到源代码后,可以对代码进行审计,容易泄露各种信息,如API、加密算法、管理员邮箱、内部功能等等

漏洞修复

  • 在生产环境中禁用 SourceMap 功能或限制 SourceMap 文件的访问权限

    // 比如在Webpack配置中禁用Source Map功能
    // webpack.config.js
    module.exports = {
      // ...
      devtool: false,
    };
    // 或者在Web服务器配置中限制Source Map文件的访问权限,以nginx为例
    # nginx configuration
    location /static/ {
      # 只允许本地访问
      allow 127.0.0.1;
      deny all;
      alias '/path/to/source-maps/';
    } 
  • 如果用的Vue框架,可以修改vue.config.js配置,如下

    # 修改
    modeule.exports = {
      productionSourceMap:false
    }
    
    # 增加
    # 方式1
    modeule.exports = {
      configureWebpack: config => {
         config.devtool = false;
         ...
      },
    }
    
    # 方式2
    modeule.exports = {
      configureWebpack: {
         devtool:false;
         ...
      },
    }
  • 删除或禁止访问正式环境中的js.map文件

鸣谢

Comments

2024-07-06

⬆︎TOP