Shakapacker环境变量泄露:EnvironmentPlugin将构建机密暴露给客户端

4 阅读2分钟

描述

自2017年起,默认的 webpack 插件将整个 process.env 传递给 EnvironmentPlugin。这种模式使得只要应用程序代码(或任何依赖)引用了 process.env.VARIABLE_NAME,就会将所有构建环境变量暴露给客户端 JavaScript 包。

这不是一个回归问题 —— 该漏洞代码自最初的 Webpacker 实现以来就已存在。Shakapacker 中最近的代码更改并未触发此问题。

影响

构建环境中任何被客户端代码(包括第三方依赖)引用的环境变量,都会直接嵌入到 JavaScript 包中。这包括:

  • DATABASE_URL —— 数据库凭证
  • AWS_SECRET_ACCESS_KEY —— AWS 凭证
  • RAILS_MASTER_KEY —— Rails 加密凭证密钥
  • STRIPE_SECRET_KEYTWILIO_AUTH_TOKEN —— 第三方 API 密钥
  • 构建环境中存在的任何其他机密信息

严重性:高危 —— 机密信息暴露在可公开访问的 JavaScript 文件中。

根本原因

原始代码使用了:

new webpack.EnvironmentPlugin(process.env)

这使得每个环境变量都可被替换。如果任何代码引用了 process.env.SECRET_KEY,该值就会被嵌入到包中。

补丁方案

升级到 9.5.0 或更高版本,该版本使用允许名单方法,默认仅暴露 NODE_ENVRAILS_ENVWEBPACK_SERVE

临时解决方法

如果开发者无法立即升级:

  • 审计客户端代码和依赖,查找任何对敏感变量的 process.env.X 引用
  • 从构建环境中移除敏感变量
  • 使用自定义 webpack/rspack 配置覆盖默认插件,采用显式的允许名单

迁移指南

升级后,如果客户端代码需要访问特定的环境变量:

选项 1:使用 SHAKAPACKER_PUBLIC_ 前缀(推荐)

# 带有此前缀的变量会被自动暴露
export SHAKAPACKER_PUBLIC_API_URL="https://api.example.com"

选项 2:使用 SHAKAPACKER_ENV_VARS

SHAKAPACKER_ENV_VARS=API_URL,FEATURE_FLAG bundle exec rails assets:precompile

需要采取的行动

升级后,轮换所有可能在先前编译的 JavaScript 包中暴露过的机密信息。

资源

参考