Skip to content

LTS-4700 / LTS-4699: clear all high-severity advisories (js-yaml, fast-uri, brace-expansion) - #21

Merged
SaranshBS merged 1 commit into
mainfrom
LTS-4700-4699-js-yaml-fast-uri
Aug 12, 2026
Merged

LTS-4700 / LTS-4699: clear all high-severity advisories (js-yaml, fast-uri, brace-expansion)#21
SaranshBS merged 1 commit into
mainfrom
LTS-4700-4699-js-yaml-fast-uri

Conversation

@MihirR-BS

@MihirR-BS MihirR-BS commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Summary

Clears every high-severity advisory in this repo: npm audit goes from 3 high → 0 high / 0 critical. GitHub's own Dependabot count for the default branch (3 high, 2 moderate) agrees.

All four packages are transitive dev-only dependencies, patched through the existing overrides block — no direct dependency changes.

Ticket Package Advisory Was Now
LTS-4700 js-yaml GHSA-5p4m-2wfm-xmqj 4.3.0 and 3.15.0 4.3.1 + 3.15.1
LTS-4699 fast-uri GHSA-7p8r-x3mc-p8w7 3.1.4 3.1.5
(not ticketed) brace-expansion GHSA-mh99-v99m-4gvg + GHSA-rgw5-rvv9-x895 1.1.16 / 2.1.2 1.1.18 / 2.1.4

Three things worth calling out

1. js-yaml had two vulnerable copies, and they need different majors

node_modules/js-yaml                                             4.3.0
node_modules/js-yaml-cloudformation-schema/node_modules/js-yaml  3.15.0

The advisory range is 3.0.0 - 3.15.0 || 4.0.0 - 4.3.0 — both are in scope. A bare "js-yaml" override would force the 3.x consumer onto 4.x, which is a breaking API change (4.x removed safeLoad). Used the version-scoped form this block already uses for brace-expansion@1/@2:

"js-yaml@3": "^3.15.1",
"js-yaml@4": "^4.3.1"

Both lines carry the same backported fix — a hash lookup replacing the linear objectKeys.indexOf() scan that made !!omap resolution O(n²) inside yaml.load().

2. fast-uri was pinned to a version that is itself vulnerable

The override said "fast-uri": "3.1.4" exactly. The advisory quoted on LTS-4699's sibling (GHSA-v2hh-gcrm-f6hx) says "upgrade to 3.1.4" — but GHSA-7p8r-x3mc-p8w7 extends the affected range to 3.0.0 - 3.1.4, so 3.1.4 is inside it. The real floor is 3.1.5.

3. Exact pins → carets

All three stale entries were exact pins, which is precisely how they aged into the vulnerable range. Carets stay within the major (no breaking jump) and let the next patch land without another PR. Matches the ip-address: ^10.4.0 precedent set in #20.

brace-expansion wasn't ticketed, but it's high-severity, sits in the same overrides block, and shows up in the same npm audit run — folding it in beats leaving it to re-raise. Note 1.1.17 only fixes the first of its two advisories; the floor is 1.1.18.

Verification

  • npm audit — 0 high, 0 critical. 6 moderate remain (qs, uuid), both unticketed and both below this repo's own audit-level=high gate in .npmrc.

  • npm ci from a clean tree — 854 packages, no peer or engine errors.

  • npm ls confirms the real installed tree, not just the lockfile:
    js-yaml@4.3.1 overridden · js-yaml@3.15.1 overridden (3.x consumer correctly stayed on 3.x) · fast-uri@3.1.5 overridden · brace-expansion@1.1.18 + @2.1.4 overridden

  • Advisory PoC replayed against both installed js-yaml copies:

    hoisted (4.x): js-yaml 4.3.1          nested (3.x): js-yaml 3.15.1
      n=10000 load=36ms                     n=10000 load=30ms
      n=20000 load=35ms  (x1.0)             n=20000 load=33ms  (x1.1)
      n=40000 load=53ms  (x1.5)             n=40000 load=50ms  (x1.5)
      n=80000 load=110ms (x2.1)             n=80000 load=101ms (x2.0)
      DUP-KEY: still rejected (YAMLException)  DUP-KEY: still rejected (YAMLException)
    

    ~2× per doubling is linear — the quadratic signature is ~4×. Duplicate-key rejection semantics unchanged on both.

  • Lockfile diff touches only these five entries — no collateral bumps.

  • All five targets published 2026-07-30/31, clearing .npmrc's min-release-age=7.

🤖 Generated with Claude Code

…ace-expansion -> 1.1.18 + 2.1.4

All four are transitive dev-only dependencies patched through the existing
`overrides` block. Every high-severity advisory in `npm audit` is cleared:
0 high, 0 critical (was 3 high).

js-yaml (LTS-4700, GHSA-5p4m-2wfm-xmqj, CVSS 7.5)
  resolveYamlOmap() enforced key uniqueness with a linear objectKeys.indexOf()
  scan per entry, making !!omap resolution O(n^2) inside yaml.load(). !!omap is
  in the default schema, so a plain yaml.load(untrusted) is affected.

  This repo carries TWO vulnerable copies, not one:
    node_modules/js-yaml                                          4.3.0
    node_modules/js-yaml-cloudformation-schema/node_modules/js-yaml  3.15.0
  Affected range is "3.0.0 - 3.15.0 || 4.0.0 - 4.3.0", so both are in scope.

  A bare `js-yaml` override would force the 3.x consumer onto 4.x, which is a
  breaking API change (4.x removed safeLoad). Used the version-scoped form the
  block already uses for brace-expansion@1/@2:
    "js-yaml@3": "^3.15.1"
    "js-yaml@4": "^4.3.1"
  Both backport the same fix — a hash lookup replacing the linear scan.

fast-uri (LTS-4699, GHSA-7p8r-x3mc-p8w7, CVSS 7.5)
  fast-uri does not treat a literal backslash as an authority delimiter while
  Node's WHATWG URL normalises it, so the two disagree on the host of the same
  string — a policy/use desync for any allowlist or SSRF filter built on it.

  The override was pinned exactly at 3.1.4, which is INSIDE the affected range
  (3.0.0 - 3.1.4). The companion advisory GHSA-v2hh-gcrm-f6hx quotes 3.1.4 as
  patched; the second one extends the range to include it. Real floor is 3.1.5.

brace-expansion (not ticketed, 2 high advisories per major line)
  GHSA-mh99-v99m-4gvg + GHSA-rgw5-rvv9-x895. Pinned at 1.1.16 / 2.1.2, both
  vulnerable; 1.1.17 only fixes the first of the two. Floors are 1.1.18 / 2.1.4.
  Same overrides block, same audit run — folded in rather than left to re-raise.

Exact pins -> carets
  The three stale pins here were all exact, which is why they aged into the
  vulnerable range. Caret stays within the major (no breaking jump) and lets the
  next patch land without a PR. Matches the `ip-address: ^10.4.0` precedent from
  LTS-4657 in this repo.

Verification
  - npm audit: 0 high / 0 critical (6 moderate remain: qs, uuid — both below the
    repo's own audit-level=high gate, both unticketed)
  - npm ci from a clean tree: 854 packages, no peer/engine errors
  - npm ls confirms the real installed tree: js-yaml@4.3.1 + js-yaml@3.15.1
    (3.x consumer stayed on 3.x), fast-uri@3.1.5, brace-expansion@1.1.18 + 2.1.4
  - advisory PoC replayed against BOTH installed js-yaml copies: growth is now
    ~2x per doubling (linear; the quadratic signature is ~4x), and duplicate-key
    rejection still throws YAMLException on each
  - lockfile diff touches only these five entries — no collateral bumps
  - all five targets published 2026-07-30/31, clearing .npmrc min-release-age=7

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@MihirR-BS
MihirR-BS requested a review from a team as a code owner August 12, 2026 13:11
@MihirR-BS
MihirR-BS requested a review from pattu777 August 12, 2026 13:11
@SaranshBS
SaranshBS merged commit 1e0a8c8 into main Aug 12, 2026
5 checks passed
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.

3 participants