Repository navigation
Patch deepmerge for CVE-2026-93753 - #411
Merged
Vladimir Morozov (vmoroz) merged 1 commit intoNov 10, 2026
Merged
Vladimir Morozov (vmoroz) merged 1 commit into
Vladimir Morozov (vmoroz) merged 1 commit into
Conversation
deepmerge 4.3.1 is the latest release and has no fix for CVE-2026-93753 (GHSA-gcqx-w48m-w2h4): a __proto__ key can set the prototype of the object that merge() returns. The maintainer closed the proposed fix, TehShrike/deepmerge#274, without merging it. Apply that fix as one shared Yarn patch in the three projects that use deepmerge through Rollup or Jest: utils/promise, tools/hermes-parser/js and API/hermes/cdp/tools/hermes-inspector-msggen. The patch drops __proto__ in both object copy loops of the source, CommonJS and UMD entry points. Each project's test script first runs a shared regression test against its installed copy. The inspector message generator has no Jest tests, so its test script now passes --passWithNoTests to Jest; without it the script always failed. Let npm-source-lint accept repository-local Yarn patch resolutions that carry Yarn's version, hash and locator parameters. It still rejects missing or out-of-repository patch files and encoded URLs. Dependabot still identifies the package as deepmerge 4.3.1, so its version-based alerts remain open.
There was a problem hiding this comment.
🟢 Approval recommended
No active review issues are recorded for the deepmerge tooling-dependency hardening change.
No open issues 🎉
What changed in this PR
Mitigates CVE-2026-93753 in three Hermes JavaScript tooling projects by applying a shared patch to deepmerge 4.3.1. The changes affect tooling dependencies, not native VM code.
Changes:
- Blocks
__proto__keys in deepmerge’s source, CommonJS, and UMD builds through shared Yarn patch resolutions. - Adds prototype-poisoning regression tests and normal-merge checks to each project’s test script.
- Updates source lint to accept parameterized local Yarn patches while retaining path and remote-source checks.
| File | Description |
|---|---|
utils/promise/yarn.lock |
Records the patched deepmerge dependency. |
utils/promise/package.json |
Applies the patch and adds regression tests. |
tools/hermes-parser/js/yarn.lock |
Records the patched deepmerge dependency. |
tools/hermes-parser/js/package.json |
Applies the patch and runs regression tests before Jest. |
API/hermes/cdp/tools/hermes-inspector-msggen/yarn.lock |
Records the patched deepmerge dependency. |
API/hermes/cdp/tools/hermes-inspector-msggen/package.json |
Applies the patch, adds regression tests, and allows an empty Jest suite. |
.yarn/patches/deepmerge-npm-4.3.1-prototype-poisoning.patch |
Filters __proto__ from both object-copy loops in all three builds. |
.ado/scripts/npm-source-lint.ts |
Handles Yarn patch parameters while preserving source validation. |
.ado/scripts/npm-source-lint.test.ts |
Covers valid patches, missing or outside paths, and encoded remote URLs. |
.ado/scripts/deepmerge.test.js |
Checks attack cases and preserves expected merge behavior. |
Review effort: Balanced
Benchmark ResultsTotal benchmarks: 204 Inputs: baseline/baseline.json, bench_result.json v8 (6176ms, 4977ms) -19.4%
test-suites (317886ms, 261461ms) -17.8%
micros (60876ms, 55888ms) -8.2%
jit-benches (8563ms, 6199ms) -27.6%
many-subclasses (73437ms, 69748ms) -5.0%
map-objects (3627ms, 1744ms) -51.9%
map-strings (4335ms, 2199ms) -49.3%
nbody (3448ms, 2395ms) -30.5%
string-switch (6503ms, 6438ms) -1.0%
raytracer (5608ms, 5390ms) -3.9%
MiniReact (30332ms, 21485ms) -29.2%
widgets (12934ms, 12323ms) -4.7%
|
Vladimir Morozov (vmoroz)
enabled auto-merge (squash)
November 10, 2026 18:42
Nikolai Aristov (NikoAri)
approved these changes
Nov 10, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Dependabot reports CVE-2026-93753
in
deepmerge@4.3.1. Rollup and Jest use it in three Yarn tool projects: thePromise bundler (
utils/promise), the hermes-parser tests, and the inspectormessage generator tests. A
__proto__key in merged input can set the prototypeof the object that
merge()returns. 4.3.1 is the latest release, and themaintainer closed the fix
(TehShrike/deepmerge#274)
without merging it, so there is nothing to upgrade to.
__proto__keys regardless of the target's shape (CVE-2026-93753) TehShrike/deepmerge#274 throughresolutionsin all three projects. It drops only__proto__in both objectcopy loops of the source, CommonJS, and UMD builds, so other keys and merge
options behave as before. Each lockfile keeps the original 4.3.1 entry and adds
one patched entry, without download URLs.
.ado/scripts/deepmerge.test.jsruns first in eachproject's
testscript. It checks the known attack shapes and normal mergesagainst that project's installed copy. The inspector generator has no Jest
tests, so its
testscript now passes--passWithNoTests; it always failedbefore.
npm-source-lintaccepts Yarn patch resolutions that carryYarn's
version,hash, andlocatorparameters when the patch file isinside the repository. Missing or outside patch files and encoded URLs are
still rejected.
Dependabot still identifies the package as deepmerge 4.3.1, so its alerts stay
open. Remove the patch and the three resolutions once upstream releases a fix.
Test Plan
Local validation with the documented anonymous PackageFeedProxy environment:
.\dev npm-source-lint: passed, 13 projects, 0 violations.node --test .\.ado\scripts\npm-source-lint.test.ts: passed, 58 tests.node .\.yarn\releases\yarn-4.13.0.cjs --cwd <project> install --immutable:passed for all three projects.
node .\.yarn\releases\yarn-4.13.0.cjs --cwd .\utils\promise test: passed.The same regression test fails against unpatched deepmerge.
node .\.yarn\releases\yarn-4.13.0.cjs --cwd .\tools\hermes-parser\js test --runInBand tooling-glob-test:passed.
node .\.yarn\releases\yarn-4.13.0.cjs --cwd .\API\hermes\cdp\tools\hermes-inspector-msggen test:passed. The generator's Babel build and
msggen --helpalso work.Promise.jswithrollup --config rollup.config.js index.jsinutils/promisegives byte-identical output with patched and unpatcheddeepmerge.
CI runs the source lint and its tests, but not these three Yarn projects. The
native build was not run; no native code changed.
Microsoft Reviewers: Open in CodeFlow