Skip to content

CVE-2026-73088 CVE-2026-73089 browserslist: Prototype write via untrusted custom stats and unbounded cache growth (-> 4.28.9) - #1123

Merged
vharseko merged 1 commit into
OpenIdentityPlatform:masterfrom
vharseko:bump/browserslist-4.28.9
Sep 7, 2026
Merged

CVE-2026-73088 CVE-2026-73089 browserslist: Prototype write via untrusted custom stats and unbounded cache growth (-> 4.28.9)#1123
vharseko merged 1 commit into
OpenIdentityPlatform:masterfrom
vharseko:bump/browserslist-4.28.9

Conversation

@vharseko

@vharseko vharseko commented Sep 7, 2026

Copy link
Copy Markdown
Member

Bumps browserslist to 4.28.9 in both UI modules — openam-ui-ria (4.25.4 -> 4.28.9) and openam-ui-js-sdk (4.28.2 -> 4.28.9) — replacing the two separate Dependabot pull requests #1121 and #1122 with a single change. Both modules sat below 4.28.7 and were therefore in the affected range of both advisories:

CVE-2026-73088 — uncaught crash and prototype write in normalizeStats()

node.js's normalizeStats() walks an untrusted stats object with a bare for...in and uses each key for plain-object bracket access. That object comes from a browserslist-stats.json file auto-discovered by walking up the directory tree from the project root — read on every browserslist() call, whatever the query — or from opts.stats / the CLI --stats= flag. Two bugs share the root cause:

  1. data[i] carries no hasOwnProperty guard, so a key that happens to name an inherited Object.prototype member (toString, valueOf, constructor, __proto__, …) resolves to that inherited function, and data[i].versions.length throws an uncaught TypeError.
  2. normalized[i] = … with i exactly "__proto__" invokes the real Object.prototype.__proto__ setter, rewriting the fresh object's [[Prototype]] instead of creating a plain property.

A poisoned browserslist-stats.json committed anywhere between the project root and the filesystem root therefore breaks every subsequent Browserslist call in that tree — including the calls Autoprefixer, Babel preset-env, PostCSS and Stylelint make internally, for entirely unrelated queries.

CVE-2026-73089 — unbounded cache growth

browserslist()'s result cache and parseQueries()'s AST cache are plain objects keyed by JSON.stringify([queries, context]) with no size cap, TTL or eviction, and browserslist.clearCaches() does not reset either one. since <year>-<month>-<day> queries accept any digit combination — Date.UTC() normalizes out-of-range values rather than rejecting them — giving an effectively unbounded space of ~17-byte cache keys that each retain a result close to the full ~8.5 KB browser list. Upstream measured over 50 MB permanently retained from 20,000 such queries, growing linearly with no observed cap. 4.28.7 replaces both caches with Maps bounded to 500 entries and oldest-first eviction.

Scope in OpenAM

browserslist is a dev-only transitive dependency in both modules, reached through @babel/helper-compilation-targets (^4.24.0) and, in openam-ui-ria, also core-js-compat (^4.25.3). It is a build-time input to Babel target resolution and does not ship in the WAR.

Neither module carries a browserslist-stats.json, a .browserslistrc, or a browserslist key in package.json, and the build issues a fixed set of queries rather than externally influenced ones, so neither advisory was exploitable in this build as it stands — the bump keeps the toolchain off the affected range and closes the door on a browserslist-stats.json arriving through a future dependency or PR. openam-ui/openam-ui-api/package-lock.json does not resolve browserslist at all, so no sibling module is left on the vulnerable version.

Verified

  • lock-file-only change, no package.json edit needed — 4.28.9 satisfies ^4.24.0, ^4.25.3 and the >= 4.21.0 peer range of update-browserslist-db
  • both halves of the diff are byte-identical to the Dependabot diffs of Bump browserslist from 4.25.4 to 4.28.9 in /openam-ui/openam-ui-ria #1121 and Bump browserslist from 4.28.2 to 4.28.9 in /openam-ui/openam-ui-js-sdk #1122; the two changes touch disjoint lock files and applied without conflict
  • all six integrity hashes match npm view <pkg> dist.integrity: browserslist@4.28.9, baseline-browser-mapping@2.11.21, caniuse-lite@1.0.30001810, electron-to-chromium@1.5.422, node-releases@2.0.54, update-browserslist-db@1.3.2
  • both lock files now resolve that identical dependency set, so the two modules stop drifting apart on the Babel target-resolution stack
  • openam-ui-ria additionally picks up the separate prototype-pollution fix of 4.28.2 and the > / >= and Electron query fixes of 4.28.5/4.28.6, which openam-ui-js-sdk already had

Upstream: 4.28.7 release · f9914ad (custom-stats fix) · f2931a3 (bounded caches) · 4.28.9 release · changelog

Closes #1121
Closes #1122

Combines dependabot PRs OpenIdentityPlatform#1121 (openam-ui-ria, 4.25.4 -> 4.28.9) and
OpenIdentityPlatform#1122 (openam-ui-js-sdk, 4.28.2 -> 4.28.9) into a single change, so both
UI modules land on the same browserslist and transitive versions:
baseline-browser-mapping 2.11.21, caniuse-lite 1.0.30001810,
electron-to-chromium 1.5.422, node-releases 2.0.54,
update-browserslist-db 1.3.2.

Upstream fixes picked up in this range: prototype pollution (4.28.2),
unbounded memory growth and a prototype write issue (4.28.7), plus
query-parsing performance improvements.

Supersedes OpenIdentityPlatform#1121, OpenIdentityPlatform#1122
@vharseko vharseko added dependencies Pull requests that update a dependency file javascript Pull requests that update Javascript code ui XUI / admin console / end-user UI labels Sep 7, 2026

@utafrali utafrali left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clean, well-scoped security update that consolidates two Dependabot bumps into one PR. The prototype pollution fix (4.28.2) and unbounded memory growth fix (4.28.7) are worth picking up promptly, and limiting changes to package-lock.json files keeps the blast radius to zero at runtime.

@vharseko vharseko added the security Security fix or hardening (CVE, GHSA, XSS/CSRF/SSRF) label Sep 7, 2026
@vharseko vharseko changed the title Bump browserslist to 4.28.9 in openam-ui-ria and openam-ui-js-sdk CVE-2026-73088 CVE-2026-73089 browserslist: Prototype write via untrusted custom stats and unbounded cache growth (-> 4.28.9) Sep 7, 2026
@vharseko
vharseko requested a review from maximthomas September 7, 2026 08:06
@vharseko
vharseko merged commit ed7c087 into OpenIdentityPlatform:master Sep 7, 2026
14 checks passed
@vharseko
vharseko deleted the bump/browserslist-4.28.9 branch September 7, 2026 08:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file javascript Pull requests that update Javascript code security Security fix or hardening (CVE, GHSA, XSS/CSRF/SSRF) ui XUI / admin console / end-user UI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants