Skip to content

UID2-7658, UID2-7659: suppress 2 CVEs in .trivyignore - #207

Closed
swibi-ttd wants to merge 1 commit into
mainfrom
swi-suppress-20260810-175827
Closed

UID2-7658, UID2-7659: suppress 2 CVEs in .trivyignore#207
swibi-ttd wants to merge 1 commit into
mainfrom
swi-suppress-20260810-175827

Conversation

@swibi-ttd

Copy link
Copy Markdown
Contributor

Suppresses 2 vulnerabilities in .trivyignore, expiry 2026-11-11 (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-67213 — HIGH, nanoid (transitive via postcss)

The DoS lives specifically in nanoid's customAlphabet/customRandom when called with size:0. In all flagged repos nanoid 3.3.16 exists only as a single transitive dependency of postcss (build-time CSS tooling for Docusaurus docs sites and CRA example apps). No repo source imports nanoid or calls customAlphabet/customRandom, and postcss itself only uses the plain default nanoid() for internal node IDs — never the vulnerable functions and never with a caller-controlled size. There is no code path, let alone an attacker-controlled size:0 input, that reaches the vulnerable loop, so the vulnerable code is unreachable despite the package being present.

Full triage report — CVE-2026-67213

CVE-2026-67213 — nanoid infinite loop (customAlphabet/customRandom, size=0)

The vulnerability

nanoid before 3.3.17 / 5.1.6 contains an infinite loop in the customAlphabet and customRandom functions. When either is configured with size: 0, the internal generation loop never satisfies its exit condition and spins forever, hanging the calling thread. Exploitation requires an application to pass an unvalidated, attacker-controlled size: 0 into one of those two specific functions.

  • Advisory: GHSA-2v37-7h3g-55p8, CVSS 3.1 AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:H (HIGH, Availability-only).
  • Installed: 3.3.16; fixed in 3.3.17 (3.x line) and 5.1.6.

How it appears in our repos

The scanner flagged four package-lock.json files across three repos. In every one, nanoid is:

  • Version 3.3.16, appearing as a single node_modules/nanoid entry.
  • Pulled in only transitively via postcss (postcss declares nanoid: "^3.3.12"). No repo declares nanoid as a direct dependency.
Repo Scanned lockfile(s) nanoid source
uid2-examples web-integrations/javascript-sdk/react-client-side & .../google-secure-signals/react-client-side postcss (via react-scripts/CRA)
uid2docs package-lock.json postcss (via Docusaurus)
uid2-docs-preview preview/package-lock.json postcss (via Docusaurus)

Reachability assessment

  1. No first-party usage. A search of all .js/.ts/.jsx/.tsx/.mjs/.cjs files across the repos found zero references to nanoid, customAlphabet, or customRandom. Our code never calls the vulnerable functions.
  2. The only consumer, postcss, does not use the vulnerable path. postcss uses nanoid solely to generate its own internal node/source-map identifiers via the plain default nanoid() export — it does not call customAlphabet or customRandom, and does not take a caller-supplied size. The specific vulnerable functions are therefore never invoked.
  3. No attacker-controlled size input. Even setting aside (2), there is no path by which external input reaches a nanoid size argument (which would need to be 0).
  4. Build-time only, not a request path. postcss runs during the static build of the Docusaurus documentation sites (uid2docs, uid2-docs-preview) and during the CRA build/start of the example React apps (uid2-examples). These are documentation and sample projects; the example server.js serves pre-built static assets and does not execute postcss at request time.

Because the vulnerable code path (customAlphabet/customRandom with size: 0) is not exercised by our code or by postcss, the CVE is unreachable in all flagged artifacts.

Decision

not_affected. The package is present (consistent with the scan) but the vulnerable path is not reachable. Per the decision logic, an available fix does not change a not_affected verdict.

Recommended remedy

Suppress this finding for the flagged repos via the repo-root .trivyignore in each. Optionally, the transitive nanoid can be bumped to ≥ 3.3.17 through the existing postcss override / dependency refresh during routine maintenance, but this is not security-required given unreachability.

GHSA-5p4m-2wfm-xmqj — HIGH, js-yaml (3.15.0 and 4.3.0, transitive npm dependency)

The advisory describes a quadratic-CPU DoS triggered by yaml.load() on untrusted YAML containing a large !!omap. In all four flagged repos js-yaml is only a dev/build-time transitive dependency (eslint, react-scripts, jest coverage, and Docusaurus's gray-matter). No production/runtime code parses attacker-controlled YAML: the portal and examples never invoke a YAML parser at runtime, and the docs sites only parse their own trusted markdown frontmatter during static-site builds. The vulnerable code path is therefore not reachable with untrusted input, so despite the affected versions being present the DoS vector does not apply.

Full triage report — GHSA-5p4m-2wfm-xmqj

GHSA-5p4m-2wfm-xmqj / CVE-2026-59870 — js-yaml quadratic !!omap DoS

What the CVE is

resolveYamlOmap() in js-yaml enforces key uniqueness for !!omap sequences with a linear objectKeys.indexOf(...) scan inside the per-element loop, making omap resolution O(n²) in the number of entries. A modestly sized YAML document with a large ordered map therefore burns disproportionate CPU inside yaml.load(), giving a denial of service against any consumer that parses untrusted YAML. !!omap is in the default schema, so plain yaml.load(untrustedInput) is enough — no custom schema needed. The 5.x fix (a Set) was never backported to 3.x/4.x; both 3.15.0 and 4.3.0 remain affected. CVSS 3.1 AV:N/AC:L/PR:N/UI:N/A:H.

Presence

Confirmed present in all four flagged repos, matching the affected versions:

  • js-yaml 3.15.0 and 4.3.0 appear throughout the npm lock files. Both repos' overrides even pin these exact (affected) versions.

Reachability analysis (per repo)

The vulnerability requires a runtime code path that feeds untrusted YAML into yaml.load(). That path does not exist in any of the flagged artifacts:

  • uid2-self-serve-portal — js-yaml 3.15.0 (hoisted) and 4.3.0 (under eslint/@eslint/eslintrc) are all "dev": true, pulled transitively by ESLint and @istanbuljs/load-nyc-config (Jest coverage). A search of src/ and server/ finds no js-yaml import and no yaml.load call. The Express backend does not parse YAML.
  • uid2-examples — 3.15.0/4.3.0 are dev/tooling transitives of eslint, react-scripts, and @istanbuljs/load-nyc-config inside static integration-example apps. No production YAML parsing.
  • uid2docs and uid2-docs-preview — Docusaurus static-site generators. js-yaml reaches a production dependency only via gray-matter (markdown frontmatter parsing) and via ESLint. gray-matter runs at build time over the repositories' own, trusted markdown — input an external attacker does not control. There is no long-running service that ingests untrusted YAML.

In short, js-yaml here is a dev-/build-time dependency. The single real parse path (Docusaurus/gray-matter) processes trusted repo-authored content during a build; a hostile payload would at most slow a CI build, not DoS a running service, and cannot be supplied by an external attacker.

Decision

not_affected. The affected code is present but the network-facing DoS vector — yaml.load() on untrusted input — is not reachable in any of the built/run artifacts. A fixed version existing (3.15.1 / 4.3.1) does not change this; the finding is non-exploitable as deployed.

Recommended action: suppress this finding for all four repos (repo-root .trivyignore). If desired for hygiene, the pinned js-yaml@3/js-yaml@4 overrides could be bumped to 3.15.1 / 4.3.1, but this is optional and not security-driving given the dependency is dev/build-time only.


Opened by uid2-vul-scan-agent (general_use_claude-opus-4-8), verdict confidence high. Please sanity-check each reachability argument before approving.

- CVE-2026-67213 (UID2-7658)
- GHSA-5p4m-2wfm-xmqj (UID2-7659)

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

Copy link
Copy Markdown
Contributor Author

Superseded by the newer suppression PR from run 20260811-110031, which carries every CVE this run did plus CVE-2026-40984 (UID2-7662) — the finding that was failing the Vulnerability Scan step here. Merge the newer PR instead; merging both would conflict on the same .trivyignore append.

@swibi-ttd swibi-ttd closed this Aug 11, 2026
@swibi-ttd
swibi-ttd deleted the swi-suppress-20260810-175827 branch August 11, 2026 01:16
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.

1 participant