fix(cli): block prototype-pollution payloads in --env parsing#14165
Conversation
The dotted-key parser in `normalizeEnvToObject` walked into `Object.prototype` when a key path started with `__proto__`, `constructor`, or `prototype`, and `setBuiltinEnvArg` used `in` (which traverses the prototype chain) to detect an existing reserved RSPACK_* flag — so an attacker controlling `--env` could pollute every plain object in the process and spoof reserved build-mode flags. Mitigations applied to packages/rspack-cli/src/utils/options.ts: - Reject any `--env` whose dotted path contains `__proto__` / `constructor` / `prototype` (aligned with lodash `_.set` hardening for CVE-2020-8203). - Build the root and every intermediate node with `Object.create(null)` so lookups can never reach `Object.prototype`. - Replace `(envName in env)` with `Object.hasOwn(env, envName)` in `setBuiltinEnvArg` so a polluted prototype cannot mask a legitimate write. Regression coverage: packages/rspack-cli/tests/utils/options.test.ts asserts the three payload shapes (`__proto__.X=Y`, `constructor.prototype.X=Y`, and reserved-flag spoofing) plus the existing nested-key happy path.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b32ca361b9
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
Pull request overview
Hardens rspack-cli’s --env dotted-key parsing against prototype-pollution payloads to prevent Object.prototype mutation and reserved RSPACK_* flag spoofing during normalizeCommonOptions.
Changes:
- Prevents dangerous path segments (
__proto__,constructor,prototype) from being applied during--envparsing. - Uses
Object.create(null)for env roots/intermediates to avoid prototype-chain lookups. - Adds unit tests covering both nested-key parsing and prototype-pollution payload shapes.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| packages/rspack-cli/src/utils/options.ts | Adds prototype-pollution hardening to --env parsing and reserved-flag writes. |
| packages/rspack-cli/tests/utils/options.test.ts | Adds tests to verify nested env parsing and protection against prototype-pollution payloads. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
📦 Binary Size-limit
🙈 Size remains the same at 61.82MB |
Merging this PR will not alter performance
Comparing Footnotes
|
Address PR #14165 review feedback: - Codex (P2): the env object is handed to the user's rspack config function `(env) => ({...})`, so changing it to a null-prototype object breaks benign callsites that do `env.hasOwnProperty(...)` or `env instanceof Object`. The dangerous-key denylist already fences off pollution at the parser entrance, so the root and intermediate nodes can stay as plain `{}` without losing the security property. - Copilot: `Object.hasOwn` requires ES2022 but the repo targets ES2021. Switch to `Object.prototype.hasOwnProperty.call`, which has the same no-prototype-lookup guarantee. Add a regression test asserting `env instanceof Object` and `env.hasOwnProperty(...)` continue to work for benign inputs.
|
Addressed both review comments in 3b44f09:
Added a regression test asserting the plain-object shape for benign inputs. All 6 unit tests green locally. |
Rsdoctor Bundle Diff AnalysisFound 5 projects in monorepo, 5 projects with changes. 📊 Quick Summary
📋 Detailed Reports (Click to expand)📁 popular-libsPath:
📁 react-10kPath:
📁 react-1kPath:
📁 react-5kPath:
📁 ui-componentsPath:
Generated by Rsdoctor GitHub Action |
Why
Harden
rspack-cli--envparsing against prototype-pollution-style key paths so that:Object.prototype(and from there leak into every plain object created later in the build)RSPACK_*build flags written by the CLI can't be overridden through the prototype chainWhat
packages/rspack-cli/src/utils/options.ts--envpaths whose segments hit a small dangerous-key denylist (lodash_.sethardening pattern).setBuiltinEnvArgnow usesObject.prototype.hasOwnProperty.callinstead ofin, so a polluted prototype can't mask a legitimate write.packages/rspack-cli/tests/utils/options.test.ts(new)Single-package change, no public API impact — the
envobject passed to user config functions keeps its plain{}shape.Credits
Reported privately via responsible disclosure by the security research team from the University of Sydney, focusing on detecting open source software vulnerabilities:
Thanks for the careful write-up and the heads-up before public disclosure.