Skip to content

UID2-7802, UID2-7803: suppress 2 CVEs in .trivyignore - #210

Merged
swibi-ttd merged 1 commit into
mainfrom
swi-suppress-20260902-114826
Sep 2, 2026
Merged

UID2-7802, UID2-7803: suppress 2 CVEs in .trivyignore#210
swibi-ttd merged 1 commit into
mainfrom
swi-suppress-20260902-114826

Conversation

@swibi-ttd

Copy link
Copy Markdown
Contributor

Suppresses 2 vulnerabilities in .trivyignore, expiry 2026-12-02 (3 months). No code fixes — each is present in the image but not reachable from this service.

Reachability alone determines suppress-vs-fix: a fixed version existing upstream does not make an unreachable path exploitable. Change any expiry in review if you want a different window.

If another suppression PR is open on this repo, this one supersedes it. Each scan run raises a fresh branch carrying every outstanding suppression, so the newest PR is a superset of the older ones — merge this and close the rest rather than merging both, which would conflict on the same append.

CVE-2026-73088 — HIGH, browserslist

The advisory's vulnerable path is normalizeStats() processing UNTRUSTED custom-stats input — a browserslist-stats.json auto-discovered on disk, opts.stats passed programmatically, or the CLI --stats= flag. Reachability therefore depends entirely on whether any such untrusted stats source is present. Direct evidence across all five repos: (1) no browserslist-stats.json (or any stats.json) exists in any repo tree; (2) no build/CI script invokes browserslist with --stats; (3) no source calls the browserslist API with opts.stats. In every repo browserslist is a transitive build-time dependency (webpack, autoprefixer, postcss, react-scripts) whose only input is the trusted, committed browserslist query array/object in package.json — that flows through the ordinary query path, not normalizeStats(). getStat() runs on every browserslist() call but returns undefined/empty when no stats file or opts.stats exists, so the unguarded for...in loop never processes attacker-controlled keys. These are static-documentation and client-side React build toolchains, not runtime services consuming external data. With no untrusted stats source anywhere, the vulnerable code path is unreachable despite the package being present.

Full triage report — CVE-2026-73088

CVE-2026-73088 — browserslist prototype pollution / DoS via normalizeStats()

Severity: HIGH (CVSS 3.1 AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H) — GHSA-73wf-gq98-2v4g
Package: browserslist 4.28.1 (installed), fixed in 4.28.7
Flagged repos: EUID-docs, uid2-examples, uid2-self-serve-portal, uid2docs, uid2-docs-preview

What the CVE is

Prior to 4.28.7, normalizeStats() in browserslist's node.js iterates untrusted custom-stats data with an unguarded for...in loop and plain bracket assignment. Inherited Object.prototype keys (__proto__, constructor, toString, …) can trigger an uncaught TypeError (denial of service) or write to the prototype of the returned object. The untrusted stats data comes from a browserslist-stats.json file auto-discovered by walking up the directory tree, from opts.stats passed programmatically, or from the CLI --stats= flag. getStat() runs on every browserslist() call, but returns nothing to normalize unless one of those stats sources is actually present.

Reachability assessment

browserslist appears in all five repos only as a transitive build-time dependency — pulled in by webpack, autoprefixer, postcss and react-scripts to resolve target browsers from each project's committed browserslist query (a static array/object in package.json, e.g. >0.2%, not dead). That query travels the normal query path, not normalizeStats().

Code search across all five repos found:

  • No browserslist-stats.json (nor any *stats*.json) anywhere in the source trees — so the on-disk auto-discovery vector cannot fire.
  • No --stats flag in any npm/build/CI script.
  • No opts.stats programmatic call in source.

With no untrusted stats source present, the vulnerable for...in loop never receives attacker-controlled input. The repos are static-documentation sites and client-side React apps (react-scripts / webpack build tooling), not runtime services that ingest external data into browserslist.

Decision

not_affected — the vulnerable code path (normalizeStats over untrusted custom stats) is unreachable in every flagged repo. A fixed version (4.28.7) exists but does not change this verdict; the finding should be suppressed. Suppression belongs in each repo's root .trivyignore. Bumping browserslist to ≥4.28.7 during routine dependency maintenance is harmless but not security-required here.

Confidence: high — based on direct absence of every untrusted-stats input across all repos, plus transitive-only, build-time usage.

CVE-2026-73089 — HIGH, browserslist

CVE-2026-73089 is an unbounded-cache DoS: browserslist retains every distinct (queries, context) result and every parseQueries AST forever, so an attacker who can drive repeated browserslist() calls with distinct query values (e.g. many 'since YYYY-MM-DD' queries) can grow memory linearly to OOM. Exploitation requires a long-lived process that invokes browserslist() with attacker-influenced query strings. In all five flagged repos browserslist is a transitive build dependency of Docusaurus (four docs sites) or react-scripts/CRA (two uid2-examples apps). It is exercised only at build time, with query values coming from the fixed 'browserslist' config field in each package.json — not from any external input. The produced artifacts are static HTML/JS bundles served without any running browserslist() code path, so no production service exposes the vulnerable function to attacker-controlled queries. The vulnerable code path is therefore unreachable. Presence is confirmed directly from the lockfiles; unreachability rests on the build-tool nature of the dependency and the absence of any runtime import, which is strong inference rather than a single grep.

Full triage report — CVE-2026-73089

CVE-2026-73089 — browserslist unbounded-cache DoS (GHSA-c83g-rgw3-j3cx)

Severity: HIGH (CVSS 3.1 AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H)
Package: browserslist < 4.28.7 — Fixed in: 4.28.7

What the CVE is

Prior to 4.28.7, browserslist's index.js keeps every distinct (queries, context) result in cache and every parseQueries() AST in parseCache with no size cap, TTL, or eviction. clearCaches() does not reset them, and the only opt-out (BROWSERSLIST_DISABLE_CACHE) is controlled by the calling application. An attacker who can influence repeated browserslist() query values — including valid since <year>-<month>-<day> queries — can drive linear memory growth and eventually crash the process with OOM.

Where it was flagged

Scanner found browserslist in six package-lock targets across five repos, all versions below the 4.28.7 fix:

  • EUID-docs — 4.28.1
  • uid2docs — 4.28.1
  • uid2-self-serve-portal — 4.28.1
  • uid2-docs-preview (preview/) — 4.28.1
  • uid2-examples google-secure-signals react-client-side — 4.26.3
  • uid2-examples javascript-sdk react-client-side — 4.28.0
Reachability analysis

In every case browserslist is pulled in transitively as build tooling:

  • The four docs sites are @docusaurus/core 3.9.2 static-site generators (scripts: docusaurus build/serve).
  • The two uid2-examples apps are react-scripts@5 (CRA) projects.

browserslist is invoked by webpack / babel-preset-env / autoprefixer at build time only, and its query input comes from the fixed browserslist config field in each package.json — never from external/attacker-controlled data. No source file imports browserslist directly. The deployed artifacts are static HTML/JS bundles; no running production service holds a long-lived process that calls browserslist() with attacker-influenced queries. The prerequisite for the DoS (repeated attacker-controlled query values in a live process) does not exist.

Decision

not_affected — the vulnerable code path is unreachable in the way these artifacts are built and served. A fixed version (4.28.7) exists but is not required to close an exploitable path here. Recommend suppressing this finding (single repo-root .trivyignore per repo). Optionally bump browserslist to ≥4.28.7 opportunistically during normal dependency maintenance, but it is not security-driven.


Opened by uid2-vul-scan-agent (general_use_claude-opus-4-8) for the automated finding(s) above. Verdict confidence: high. Please sanity-check each reachability argument before approving.

- CVE-2026-73088 (UID2-7802)
- CVE-2026-73089 (UID2-7803)

Each is present but not reachable from this service; see the linked tickets for the per-CVE impact assessments. Reachability alone determines suppress-vs-fix.
@swibi-ttd
swibi-ttd merged commit 1ff08c1 into main Sep 2, 2026
3 checks passed
@swibi-ttd
swibi-ttd deleted the swi-suppress-20260902-114826 branch September 2, 2026 06:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants